Bzoj3262 陌上花开
Submit: 1755 Solved: 764
Description
有n朵花,每朵花有三个属性:花形(s)、颜色(c)、气味(m),又三个整数表示。现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb。显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。
Input
第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值。
以下N行,每行三个整数si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的属性
Output
包含N行,分别表示评级为0...N-1的每级花的数量。
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
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
1
3
0
1
0
1
0
0
1
HINT
1 <= N <= 100,000, 1 <= K <= 200,000
CDQ分治
三维排名,第一维先排序,当做是时间,后两维铺在平面上,当做是平面上的修改。
于是原问题可以看成一个按一定顺序添加点,然后询问某时间某个点左下方有多少点的问题。
可用CDQ分治做。
代码学(chao)自hzwer
注释掉的代码看上去思路一样,但不知道为什么会WA,姑且放着。
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 const int mxn=100010; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 struct flw{ 17 int s,c,m,id,ct; 18 }f[mxn],a[mxn]; 19 int ans[mxn]; 20 int n,k; 21 int cmp(flw a,flw b){ 22 if(a.s!=b.s)return a.s<b.s; 23 if(a.c!=b.c)return a.c<b.c; 24 return a.m<b.m; 25 } 26 int cmp1(flw a,flw b){ 27 if(a.c==b.c)return a.m<b.m; 28 return a.c<b.c; 29 } 30 int t[mxn<<1]; 31 void add(int x,int v){while(x<=k){t[x]+=v;x+=x&-x;}} 32 int smm(int x){int res=0;while(x){res+=t[x];x-=x&-x;}return res;} 33 int cnt=0; 34 void CDQ(int l,int r){ 35 if(l==r){ 36 // a[l].id+=a[l].ct-1; 37 return; 38 } 39 int i,j,mid=(l+r)>>1; 40 CDQ(l,mid);CDQ(mid+1,r); 41 sort(a+l,a+mid+1,cmp1);sort(a+mid+1,a+r+1,cmp1); 42 i=l,j=mid+1; 43 while(j<=r){ 44 while(i<=mid && a[i].c<=a[j].c){ 45 add(a[i].m,a[i].ct); 46 i++; 47 } 48 a[j].id+=smm(a[j].m); 49 j++; 50 } 51 for(j=l;j<i;j++)add(a[j].m,-a[j].ct); 52 return; 53 } 54 int main(){ 55 int i,j; 56 n=read();k=read(); 57 for(i=1;i<=n;i++){ 58 f[i].s=read();f[i].c=read();f[i].m=read(); 59 // f[i].ct++; 60 } 61 sort(f+1,f+n+1,cmp); 62 /* 63 for(i=1;i<=n;i++){ 64 if(f[i-1].s<=f[i].s && f[i-1].c<=f[i].c && f[i-1].m<=f[i].m){ 65 a[++cnt]=f[i]; 66 } 67 else a[cnt].ct++; 68 }*/ 69 int tt=0; 70 for(i=1;i<=n;i++){ 71 tt++; 72 if(f[i].s!=f[i+1].s || f[i].c!=f[i+1].c || f[i].m!=f[i+1].m){ 73 a[++cnt]=f[i]; 74 a[cnt].ct=tt; 75 tt=0; 76 } 77 } 78 CDQ(1,cnt); 79 for(i=1;i<=cnt;i++){ 80 ans[a[i].id+a[i].ct-1]+=a[i].ct; 81 } 82 for(i=0;i<n;i++){ 83 printf("%d\n",ans[i]); 84 } 85 return 0; 86 }
本文为博主原创文章,转载请注明出处。