​http://www.elijahqi.win/archives/1704​​​
背景
在Z某的家中有一个显示屏
显示着班级中船的分布情况
Z某最近在练习“船位预估”技能
所以他会在每天早上做出一些询问
到晚上再来查看结果
2017.11.2
Z某的显示屏被人黑了,软硬件均有损坏
Z某请你为他维修

描述
支持两个操作
Q x y表示询问[1~x][1~y]区间内的船数
C x y表示点(x, y)处增加一条船

输入
第一行一个整数N
接下来N行,一行一个操作

输出
对每个询问,一行一个答案

样例
输入
3
Q 1 2
C 1 2
Q 2 2
Copy
输出
0
1
Copy
范围
40% N=10
80% N=

10^3

103
100% N=

10^5+10^5

105+105 1<=x, y<=10000

限制
1000ms
128M

给定坐标系中的一些点
每次可以加1
或者查阅前缀(x,y)区间的前缀和是多少
那么这题可以多层数据结构嵌套 但显然编程复杂度太高
那么cdq分治
这个相当于是一个三维偏序的拓展问题
首先第一维我们认为是按照询问的时间排序
然后第二维按照x坐标排序 第三维我们建立树状数组前缀和统计 我们对所有询问二分
然后先处理左同时把可能对右边的影响加入 (树状数组) 然后在处理右边的时候 如果遇到询问则加入 然后每次类似归并排序后注意将树状数组清空
这位大佬讲的挺好的

#include<cstdio>
#define N 220000
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S) {T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0;char ch=gc();
while(ch<'0'||ch>'9') ch=gc();
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}
return x;
}
struct node{
int time,x,y,type;
}query[N],tmp[N];
int s[N],ans[N],n;bool flag[N];
inline void add(int x,int v){
for (int i=x;i<=1e4;i+=i&(-i)) s[i]+=v;
}
inline void clear(int x){
for (int i=x;i<=1e4;i+=i&(-i)) if (s[i]) s[i]=0;else return;
}
inline int qr(int x){
int tt=0;for (int i=x;i;i-=i&(-i)) tt+=s[i];return tt;
}
void cdq(int l,int r){
if (l==r) return;
int mid=l+r>>1;cdq(l,mid);cdq(mid+1,r);
int h1=l,h2=mid+1,op=l;
while(h1<=mid&&h2<=r){
if (query[h1].x<query[h2].x||((query[h1].x==query[h2].x)&&query[h1].type<query[h2].type)){
if (query[h1].type==1) add(query[h1].y,1);tmp[op++]=query[h1++];}
else{if (query[h2].type==2) ans[query[h2].time]+=qr(query[h2].y);tmp[op++]=query[h2++];}
}
while(h1<=mid) {if (query[h1].type==1) add(query[h1].y,1); tmp[op++]=query[h1++];}
while(h2<=r) {if (query[h2].type==2) ans[query[h2].time]+=qr(query[h2].y); tmp[op++]=query[h2++];}
for (int i=l;i<=r;++i) {
query[i]=tmp[i]; if(query[i].type==1) clear(query[i].y);
}
}
int main(){
freopen("a.in","r",stdin);
n=read();
for (int i=1;i<=n;++i) {
char ch=gc();while(ch!='Q'&&ch!='C') ch=gc();query[i].time=i;
if (ch=='Q') query[i].type=2,flag[i]=1;else query[i].type=1;
query[i].x=read();query[i].y=read();
}cdq(1,n);
//for (int i=1;i<=n;++i) printf("%d %d %d %d\n",query[i].x,query[i].y,query[i].time,query[i].type);
for (int i=1;i<=n;++i) if (flag[i]) printf("%d\n",ans[i]);
return 0;
}