0
点赞
收藏
分享

微信扫一扫

HDOJ  4325  Flowers


题目:​​http://acm.hdu.edu.cn/showproblem.php?pid=4325​​

题目自解:将开花时间和闭花时间进行排序,

某时刻开花的数减去花谢的数就是正在盛开的花的数目,用二分法查找

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int a[100005],b[1000005];
int see[100005][2];
int n,m;
int Find(int time)
{
int low=0,high=n-1,mid;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid]==time)
{
while(mid<n&&a[++mid]==time);
return mid;
}
if(a[mid]<time)
low=mid+1;
else
high=mid-1;
}
return low;
}
int Search(int time)
{
int low=0,high=n-1,mid;
while(low<=high)
{
mid=(low+high)/2;
if(b[mid]==time)
{
while(mid>=0&&b[--mid]==time);
return mid+1;
}
if(b[mid]<time)
low=mid+1;
else
high=mid-1;
}
return low;
}
int cmp( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
int main()
{
int h=1,t,i,j;
scanf("%d",&t);
while(t--)
{
memset(see,0,sizeof(see));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d%d",&a[i],&b[i]);
printf("Case #%d:\n",h++);
qsort(a,n,sizeof(a[0]),cmp);
qsort(b,n,sizeof(b[0]),cmp);
for(i=0;i<m;i++)
scanf("%d",&see[i][0]);
for(j=0;j<m;j++)
see[j][1]=Find(see[j][0])-Search(see[j][0]);
for(i=0;i<m;i++)
printf("%d\n",see[i][1]);
}
return 0;
}


还有题解给的是:这个题就是比较裸的区间更新,单点查询的线段树。一开始需要把要查询的点和花开的时间和花谢的时间一起离散化了,这样查询的时候就方便多了。

#include<cstdio>
#include<map>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=100010;
struct eee{int st,end;}ee[N];
int foruse[N];
int nt[N];
int size;
int getvalue(int i)
{
int l=0,r=size;
while(l+1<r)
{
int mid=(r+l)/2;
if(foruse[mid]<=i)
{
l=mid;
}
else r=mid;
}
return r;
}int lowbit(int num)
{
return num&(num^(num-1));
}void add(int num,int pos)
{
while(pos<N)
{
nt[pos]+=num;
pos+=lowbit(pos);
}
}int get(int pos)
{
int ret=0;
while(pos>0)
{
ret+=nt[pos];
pos-=lowbit(pos);
}
return ret;
}int main()
{
freopen("data.in","r",stdin);
freopen("data3.out","w",stdout);
int ti;
scanf("%d",&ti);
for(int ca=1;ca<=ti;ca++)
{
int n,m;
int cnt=0;
int *it;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
int t1,t2;
scanf("%d%d",&t1,&t2);
ee[i].st=t1;
ee[i].end=t2+1;
foruse[2*i+1]=t1;
foruse[2*i+2]=t2+1;
}
sort(foruse+1,foruse+2*n+1);
it=unique(foruse+1,foruse+2*n+1);
size=it-foruse;
foruse[0]=0;foruse[size]=1e9+1;
memset(nt,0,sizeof(nt));
for(int i=0;i<n;i++)
{
add(1,getvalue(ee[i].st));
add(-1,getvalue(ee[i].end));
}
printf("Case #%d:\n",ca);
for(int i=0;i<m;i++)
{
int t;
scanf("%d",&t);
printf("%d\n",get(getvalue(t)));
}
}
return 0;
}


因为我的线段树还没有学习呢,所以感觉第一种比较简单,好理解

举报

相关推荐

0 条评论