3262: The flowers bloom on the mo
Time limit:20 Sec Memory limit:256 MB
submit:366 solved:163
[Submit] [Status] [Discuss]
Description
There are n flowers, each flower has three attributes: Flower shape (s), color (c), Odor (m), and three integers. Now, to rate each flower, the level of a flower is the number of flowers that it can surpass. Define a flower a than another flower B to be beautiful, when and only if sa>=sb,ca>=cb,ma>=mb. Obviously, two flowers may have the same properties. The number of flowers to be rated for each level needs to be counted.
Input
The first behavior n,k (1 <= N <= 100,000, 1 <= K <= 200,000), respectively, represents the number of flowers and the maximum attribute value.
The following n lines, three integers per line si, CI, mi (1 <= si, CI, mi <= K), representing the properties of the flower of the I
Output
Contains n rows, each representing a rating of 0 ... N-1 the number of flowers per level.
Sample Input
10 3
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1
Sample Output
3
1
3
0
1
0
1
0
0
1
HINT
1 <= N <= 100,000, 1 <= K <= 200,000
I can do this problem by CDQ (tree sets of trees).
Maintain three-dimensional partial order:
First-dimensional sorting, second-CDQ, third-dimensional tree-like arrays.
First we can combine the three dimensions into one, one calculation.
We sort by s, and then we assign them to 1. Tot (the S analogy can be an ID here).
Next, sort by C and start CDQ Division.
To calculate the effect of the left side on the right:
① s on the left are smaller than the right
② on each side C is also incremented in turn
③ We just scan to the right, the left C is less than the current flower of the flower m added to the tree array, the current tree array of M less than equal to the current scan of the number of M of the flower is the left three-dimensional is less than or equal to the current number of flowers.
#include <iostream>#include <algorithm>#include <cmath>#include <cstring>#include <cstdio>#include <cstdlib>#define M 500005using namespace Std;intNow,n,ans[m],k;struct data{intCs,m, Num,ans;} A[m],b[m],Q[m]; struct bit{intV,t;} T[m *];voidRead(int&TMP) {tmp=0; Char Ch=getchar ();intfu=1; for(;ch<' 0 '|| Ch>' 9 '; Ch=getchar ())if(ch=='-') fu=-1; for(; ch>=' 0 '&&ch<=' 9 '; Ch=getchar ()) tmp=tmp*10+ch-' 0 '; Tmp*=Fu;} BOOL CMP (data A,data b) {if(A.s==b.s&&A.C==B.C)returnA.m<b.m;if(A.s==b.s)returna.c<b.c;returnA.s<b.s; }bool CMP2 (data a,data b) {if(A.c==b.c&&a.s==b.s)returnA.m<b.m;if(A.C==B.C)returnA.s<b.s;returnA.C<B.C;}intLowbit (int x){return x& (-x);} void Update (int x,intP) { for(intI=x; I<=k;i+=lowbit (i)) {if(T[i]. T==now) t[i].v+=p;ElseT[i]. T=now,t[i].v=p; }}intGetsum (int x){intcn1=0; for(intI=x; I;i-=lowbit (i))if(T[i]. T==now) ans+=t[i].v;returnAns;} void CDQ (intLintR) {if(L==R) {a[l].ans+= (a[l].num-1);return; }int m= (l+r) >>1;intQ1=l,q2=m+1; for(inti=l;i<=r;i++)if(q1<=m&&a[i].s<=m)q[q1++]=a[i];Else q[q2++]=a[i]; for(inti=l;i<=r;i++) a[i]=Q[i]; CDQ (L,m); now++;intJ=l; for(intI=m+1; i<=r;i++) { for(; j<=m; j + +)if(A[I].C>=A[J].C) Update (A[J).m, A[j].num);Else Break; A[i].ans+=getsum (A[i].m); } CDQ (m+1, R); Q1=l,q2=m+1; for(inti=l;i<=r;i++)if((a[q1].c<=a[q2].c| | Q2>R) &&q1<=m)Q[i]=a[q1++];Else Q[i]=a[q2++]; for(inti=l;i<=r;i++) a[i]=Q[i];}intMain () {now=0;Read(n);Read(k); for(intI=1; i<=n;i++)Read(A[i].s),Read(A[I].C),Read(A[i].m), a[i].num=1;Sort(A +1, A +1+N,CMP);inttot=0; for(intI=1; i<=n;i++) {intK= (A[i].s==a[i-1].s) & (a[i].c==a[i-1].C) & (A[i].m==a[i-1].m);if(i==1||! k) A[++tot]=a[i];Elsea[tot].num++; } for(intI=1; i<=tot;i++) A[i].s=i,a[i].ans=0;Sort(A +1, A +1+TOT,CMP2); CDQ (1, tot); for(intI=1; i<=tot;i++) Ans[a[i].ans]+=a[i].num; for(intI=0; i<n;i++)printf("%d\ n", Ans[i]);return 0;}
In fact, the beginning of the CDQ division is not the case, I was in the CDQ division in the Order of C, C as similar to the ID of the thing to separate left to the right, then there will be a problem, there are multiple C the same time who on the left who on the right?
I use a variable C record to the left there are several with the median value, nn as the time of the scan counter (statistics is currently equal to the median value of a few), when the counter is greater than or equal to C, and then hit the right side of C directly on.
(This method code takes a long time: )
#include <iostream>#include <algorithm>#include <cmath>#include <cstring>#include <cstdio>#include <cstdlib>#define M 500005using namespace Std;intNow,n,ans[m],k;struct data{intCs,m, Num,ans;} A[m],b[m],Q[m]; struct bit{intV,t;} T[m *];voidRead(int&TMP) {tmp=0; Char Ch=getchar ();intfu=1; for(;ch<' 0 '|| Ch>' 9 '; Ch=getchar ())if(ch=='-') fu=-1; for(; ch>=' 0 '&&ch<=' 9 '; Ch=getchar ()) tmp=tmp*10+ch-' 0 '; Tmp*=Fu;} BOOL CMP (data A,data b) {if(A.s==b.s&&A.C==B.C)returnA.m<b.m;if(A.s==b.s)returna.c<b.c;returnA.s<b.s; }bool CMP2 (data a,data b) {returnA.C<B.C;}intLowbit (int x){return x& (-x);} void Update (int x,intP) { for(intI=x; I<=k;i+=lowbit (i)) {if(T[i]. T==now) t[i].v+=p;ElseT[i]. T=now,t[i].v=p; }}intGetsum (int x){intans=0; for(intI=x; I;i-=lowbit (i))if(T[i]. T==now) ans+=t[i].v;returnAns;} void CDQ (intLintR) {if(L==R) {a[l].ans+= (a[l].num-1);return; }int m= (l+r) >>1;intQ1=l,q2=m+1; for(inti=l;i<=r;i++) B[i]=a[i];Sort(b+l,b+1+R,CMP2);int x=b[m].C;intC=1, mm=m, nn=0; while(mm-1>=l&&b[mm-1].c==x) mm--, C + +; for(inti=l;i<=r;i++) {if(q1<=m&&a[i].c<=x) {if(a[i].c==x&&NN==C)q[q2++]=a[i];Else{if(a[i].c==x) nn++;q[q1++]=a[i]; } }Else q[q2++]=a[i]; } for(inti=l;i<=r;i++) a[i]=Q[i]; CDQ (L,m); now++;intJ=l; for(intI=m+1; i<=r;i++) { for(; j<=m; j + +)if(A[i].s>=A[J].s) Update (A[j].m, A[j].num);Else Break; A[i].ans+=getsum (A[i].m); } CDQ (m+1, R); Q1=l,q2=m+1; for(inti=l;i<=r;i++)if((A[Q1).s<A[Q2].s|| Q2>R) &&q1<=m)Q[i]=a[q1++];Else Q[i]=a[q2++]; for(inti=l;i<=r;i++) a[i]=Q[i];}intMain () {now=0;Read(n);Read(k); for(intI=1; i<=n;i++)Read(A[i].s),Read(A[I].C),Read(A[i].m), a[i].num=1;Sort(A +1, A +1+N,CMP);inttot=0; for(intI=1; i<=n;i++) {intK= (A[i].s==a[i-1].s) & (a[i].c==a[i-1].C) & (A[i].m==a[i-1].m);if(i==1||! k) A[++tot]=a[i];Elsea[tot].num++; } for(intI=1; i<=tot;i++) A[i].s=i,a[i].ans=0; CDQ (1, tot); for(intI=1; i<=tot;i++) Ans[a[i].ans]+=a[i].num; for(intI=0; i<n;i++)printf("%d\ n", Ans[i]);return 0;}
(WA is because there is no consideration for multiple C in the same situation)
"Bzoj 3262" on the flower Open