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 }

 

posted @ 2016-08-24 14:38  barriery  阅读(230)  评论(0编辑  收藏  举报