好文艺的题目。
自己犯的**错误不想再提了,特别注意这题要求三个都相等时也计入统计,所以就特别处理一下。
裸的三位偏序,CDQ+树状数组
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=200005; 4 const int M=400005; 5 int n,k,tim,ans[N],t[M],v[M],f[N],cnt,top; 6 struct node 7 { 8 int s,c,m,id,num; 9 }q[M],qq[M]; 10 inline int lowbit(int x){return x&(-x);} 11 void add(int x,int w) 12 { 13 for(;x<=k;x+=lowbit(x)) 14 { 15 if(tim!=v[x]) 16 { 17 v[x]=tim;t[x]=w; 18 } 19 else t[x]+=w; 20 } 21 } 22 int query(int x) 23 { 24 int an=0; 25 for(;x;x-=lowbit(x)) 26 { 27 if(v[x]==tim)an+=t[x]; 28 } 29 return an; 30 } 31 bool cmp1(node a,node b) 32 { 33 if(a.s==b.s) 34 { 35 return a.c==b.c?a.m<b.m:a.c<b.c; 36 } 37 return a.s<b.s; 38 } 39 bool cmp2(node a,node b) 40 { 41 return a.c==b.c?a.m<b.m:a.c<b.c; 42 } 43 void solve(int l,int r) 44 { 45 if(l==r)return; 46 int mid=(l+r)>>1; 47 solve(l,mid);solve(mid+1,r); 48 sort(q+l,q+mid+1,cmp2);sort(q+mid+1,q+r+1,cmp2); 49 int i=l,j=mid+1;tim++; 50 while(j<=r) 51 { 52 while(i<=mid&&q[i].c<=q[j].c)add(q[i].m,q[i].num),++i; 53 q[j].sum+=query(q[j].m);++j; 54 } 55 } 56 int main() 57 { 58 scanf("%d%d",&n,&k); 59 for(int i=1;i<=n;++i) 60 { 61 scanf("%d%d%d",&qq[i].s,&qq[i].c,&qq[i].m); 62 }sort(qq+1,qq+n+1,cmp1); 63 for(int i=1;i<=n;++i) 64 { 65 cnt++; 66 if(qq[i].c!=qq[i+1].c||qq[i].s!=qq[i+1].s||qq[i].m!=qq[i+1].m) 67 { 68 q[++top]=qq[i];q[top].num=cnt;cnt=0; 69 } 70 } 71 solve(1,top); 72 for(int i=1;i<=top;++i) 73 ans[q[i].sum+q[i].num-1]+=q[i].num; 74 for(int i=0;i<n;++i)printf("%d\n",ans[i]); 75 return 0; 76 }