三维偏序是一个很经典的东西啊。
//结果蒟蒻我居然是先写的四维的?
第一位排序当作限制,然后cdq分治+树状数组统计就好。写起来很快的啊。
题目:bzoj3262 陌上花开
1 #include<bits/stdc++.h> 2 #define N 100005 3 using namespace std; 4 int n,m,c[2*N],ans[N]; 5 struct Node{int a,b,c,s,ans;}a[N],p[N]; 6 inline bool cmp(Node x,Node y){ 7 if(x.a==y.a&&x.b==y.b)return x.c<y.c; 8 if(x.a==y.a)return x.b<y.b; 9 return x.a<y.a; 10 } 11 inline bool operator<(Node x,Node y){ 12 if(x.b==y.b)return x.c<y.c; 13 else return x.b<y.b; 14 } 15 inline int lowbit(int x){return x&(-x);} 16 inline void add(int x,int val){ 17 for(int i=x;i<=m;i+=lowbit(i))c[i]+=val; 18 } 19 inline int ask(int x){ 20 int ans=0; 21 for(int i=x;i;i-=lowbit(i))ans+=c[i]; 22 return ans; 23 } 24 void solve(int l,int r){ 25 if(l==r)return; 26 int mid=(l+r)>>1; 27 solve(l,mid);solve(mid+1,r); 28 sort(p+l,p+mid+1);sort(p+mid+1,p+r+1); 29 int i=l,j=mid+1; 30 while(j<=r){ 31 while(i<=mid&&p[i].b<=p[j].b){add(p[i].c,p[i].s);i++;} 32 p[j].ans+=ask(p[j].c);j++; 33 } 34 for(int j=l;j<i;j++)add(p[j].c,-p[j].s); 35 } 36 inline int read(){ 37 int f=1,x=0;char ch; 38 do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); 39 do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); 40 return f*x; 41 } 42 int main(){ 43 int nn=read();m=read(); 44 for(int i=1;i<=nn;i++)a[i].a=read(),a[i].b=read(),a[i].c=read(); 45 sort(a+1,a+nn+1,cmp);int cnt=0; 46 for(int i=1;i<=nn;i++){ 47 cnt++; 48 if(a[i].a!=a[i+1].a||a[i].b!=a[i+1].b||a[i].c!=a[i+1].c){ 49 p[++n]=a[i];p[n].s=cnt;cnt=0; 50 } 51 } 52 solve(1,n); 53 for(int i=1;i<=n;i++)ans[p[i].ans+p[i].s-1]+=p[i].s; 54 for(int i=0;i<nn;i++)printf("%d\n",ans[i]); 55 return 0; 56 }