C++之路进阶——bzoj3262(陌上花开)

F.A.QsHomeDiscussProblemSetStatusRanklistContestModifyUser   gryz2016Logout捐赠本站
Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入、输出语句及数据类型及范围,避免无谓的RE出现。

3262: 陌上花开

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 812  Solved: 361
[Submit][Status][Discuss]

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

Source

题解:

     三维片续集,将a排序,用树状数组插入b,再在树状数组中建立treap,维护c。

代码:

     

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #define M 5000005
 6 
 7 using namespace std;
 8 
 9 int n,m,tmp,sz,ans[100005],sum[100005],root[200005],s[M],ls[M],rs[M],rond[M],v[M],w[M];
10 
11 struct ss
12    {
13        int a;
14        int b;
15        int c;
16    }a[M];
17    
18 bool cmp (ss a,ss b)
19   {
20       if (a.a==b.a&&a.b==b.b) return a.c<b.c;
21       if (a.a==b.a) return a.b<b.b;
22       return a.a<b.a;
23   }
24     
25 int lowbit(int x) {return x&(-x);}      
26 
27 void updata(int k) {s[k]=s[ls[k]]+s[rs[k]]+w[k];}
28 
29 int rturn(int &k) {int t=ls[k];ls[k]=rs[t];rs[t]=k;s[t]=s[k];updata(k);k=t;}
30 
31 int lturn(int &k) {int t=rs[k];rs[k]=ls[t];ls[t]=k;s[t]=s[k];updata(k);k=t;}
32 
33 void ins (int &k,int num)
34    {
35         if (!k) {k=++sz;rond[k]=rand();s[k]=w[k]=1;v[k]=num;return;}
36         s[k]++;
37         if (num==v[k]) {w[k]++;return;}
38         else
39            if (num<v[k]) {ins(ls[k],num);if (rond[ls[k]]<rond[k]) rturn(k);}
40               else {ins(rs[k],num);if (rond[rs[k]]<rond[k])lturn(k);}              
41    }
42 
43 void getrank(int k,int num)
44     {
45       if (!k) return;    
46       if (num==v[k]) {tmp+=s[ls[k]]+w[k];return;}    
47        num>=v[k]? tmp+=s[ls[k]]+w[k],getrank(rs[k],num):getrank(ls[k],num); 
48     } 
49 
50 void insert(int x,int num)
51     {
52         for (int i=x;i<=m;i+=lowbit(i))
53           ins(root[i],num);
54     }
55 
56 void ask(int x,int num)
57    {
58         for(int i=x;i;i-=lowbit(i)) 
59            getrank(root[i],num);
60    }
61    
62 int main()
63    {
64         scanf("%d%d",&n,&m);
65         for (int i=1;i<=n;i++)
66           scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].c);
67         sort(a+1,a+n+1,cmp);
68         for (int i=1;i<=n;i++)
69            {
70               if (a[i].a==a[i+1].a&&a[i].b==a[i+1].b&&a[i].c==a[i+1].c&&i!=n)    
71                   sum[i+1]=sum[i]+1;
72                     else
73                       {
74                             tmp=0;
75                             ask(a[i].b,a[i].c);
76                       ans[tmp]+=sum[i]+1;         
77                       }
78                 insert(a[i].b,a[i].c);      
79             } 
80     for(int i=0;i<n;i++)
81         printf("%d
",ans[i]);         
82    }


HOME Back


原文地址:https://www.cnblogs.com/grhyxzc/p/5147270.html