Counting Stars
Counting Stars
题目链接:http://acm.xidian.edu.cn/problem.php?id=1177
离线+树状数组
一眼扫过去:平面区间求和,1e6的数据范围,这要hash+二维树状数组吧?这么短时间我肯定调不出来,果断弃...
结束后有人说一维树状数组可以做,ヾ(。`Д´。)离线啊没想到。
然后就成了水题...(坐标要++,因为是从零开始的)
感悟:离线算法在某种情况下可以降低复杂度的维度。
代码如下:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define met(a,b) memset(a,b,sizeof(a)) 5 #define N 200005 6 #define M 1000001 7 using namespace std; 8 struct nod{ 9 int x,y,index,type,v; 10 }a[N]; 11 int tree[M]; 12 bool cmp(nod a,nod b){ 13 if(a.y==b.y)return a.x<b.x; 14 else return a.y<b.y; 15 } 16 bool recover(nod a,nod b){ 17 if(a.type==b.type)return a.index<b.index; 18 else return a.type<b.type; 19 } 20 int n,m,x,y,k; 21 void init(){ 22 met(a,0); 23 met(tree,0); 24 } 25 int lowbit(int x){ 26 return x&(-x); 27 } 28 void add(int x){ 29 for(int i=x;i<M;i+=lowbit(i)) 30 tree[i]++; 31 } 32 int query(int x){ 33 int sum=0; 34 for(int i=x;i>0;i-=lowbit(i)) 35 sum+=tree[i]; 36 return sum; 37 } 38 int main(void){ 39 for(int times=1;~scanf("%d%d",&n,&m);++times){ 40 init(); 41 for(k=0;k<n;++k){ 42 scanf("%d%d",&x,&y); 43 x++,y++; 44 a[k].x=x; 45 a[k].y=y; 46 a[k].type=2; 47 } 48 for(;k<n+m;++k){ 49 scanf("%d%d",&x,&y); 50 x++,y++; 51 a[k].x=x; 52 a[k].y=y; 53 a[k].type=1; 54 a[k].index=k-n; 55 } 56 sort(a,a+k,cmp); 57 printf("Case #%d:\n",times); 58 for(int i=0;i<k;++i){ 59 if(a[i].type==2)add(a[i].x); 60 else a[i].v=query(a[i].x); 61 } 62 sort(a,a+k,recover); 63 for(int i=0;i<m;++i) 64 printf("%d\n",a[i].v); 65 } 66 }