标签:scan 移动 names 系统 tps printf 题解报告 https 矩形
摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统。和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米。但其真正高科技之处在于,它能够回答形如“给定区域内有多少名用户?”的问题。
在定位系统中,世界被认为是一个W×W的正方形区域,由1×1的方格组成。每个方格都有一个坐标(x,y),1<=x,y<=W。坐标的编号从1开始。对于一个4×4的正方形,就有1<=x<=4,1<=y<=4(如图):
请帮助Mokia公司编写一个程序来计算在某个矩形区域内有多少名用户。
输入格式:
有三种命令,意义如下:
命令 参数 意义
输出格式:
对所有命令2,输出一个一行整数,即当前询问矩形内的用户数量。
对于所有数据:
1<=W<=2000000
1<=X1<=X2<=W
1<=Y1<=Y2<=W
1<=x,y<=W
0<A<=10000
命令1不超过160000个。
命令2不超过10000个。
【思路分析】
CDQ模板题,由于网上博客看不懂,所以只有自行脑补,可能写得有点丑,有点慢。。。自行体会。。。
【代码实现】
1 #include<cstdio> 2 #include<algorithm> 3 #define lowbit(x) x&(-x) 4 using namespace std; 5 const int N=2e6+5; 6 struct sd{ 7 int kind,x,y,val,id; 8 }que[N]; 9 int ans[N],t[N<<2],n,w,ord,cnt,cot; 10 bool cmp(sd a,sd b) 11 { 12 if(a.x!=b.x) return a.x<b.x; 13 if(a.y!=b.y) return a.y<b.y; 14 return a.kind<b.kind; 15 } 16 void add(int v,int ww) 17 { 18 for(;v<=w;v+=lowbit(v)) 19 t[v]+=ww; 20 } 21 int ask(int v) 22 { 23 int res=0; 24 for(;v;v-=lowbit(v)) 25 res+=t[v]; 26 return res; 27 } 28 void CDQ(int l,int r) 29 { 30 if(l==r) return; 31 int mid=(l+r)>>1; 32 CDQ(l,mid),CDQ(mid+1,r); 33 sort(que+l,que+mid+1,cmp),sort(que+mid+1,que+r+1,cmp); 34 int i=l,j=mid+1; 35 for(;j<=r;j++) 36 { 37 while(que[i].x<=que[j].x&&i<=mid) 38 { 39 if(!que[i].kind) add(que[i].y,que[i].val); 40 i++; 41 } 42 if(que[j].kind) ans[que[j].id]+=que[j].val*ask(que[j].y); 43 } 44 for(j=l;j<i;j++) if(!que[j].kind) add(que[j].y,-que[j].val); 45 } 46 int main() 47 { 48 scanf("%d%d",&n,&w); 49 while(1) 50 { 51 int a,b,c,d; 52 scanf("%d",&ord);if(ord==3) break; 53 scanf("%d%d%d",&a,&b,&c); 54 if(ord==1) {que[++cnt]=(sd){0,a,b,c,0};} 55 if(ord==2) 56 { 57 scanf("%d",&d); 58 que[++cnt]=(sd){1,a-1,b-1,1,++cot}; 59 que[++cnt]=(sd){1,c,d,1,cot}; 60 que[++cnt]=(sd){1,a-1,d,-1,cot}; 61 que[++cnt]=(sd){1,c,b-1,-1,cot}; 62 } 63 } 64 CDQ(1,cnt); 65 for(int i=1;i<=cot;i++) printf("%d\n",ans[i]); 66 return 0; 67 }
标签:scan 移动 names 系统 tps printf 题解报告 https 矩形
原文地址:https://www.cnblogs.com/genius777/p/9124398.html