Bzoj3262 陌上花开

Time Limit: 20 Sec  Memory Limit: 256 MB
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

Sample Output

3
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
",ans[i]);
84     }
85     return 0;
86 }
原文地址:https://www.cnblogs.com/SilverNebula/p/6270224.html