BZOJ3262 陌上花开

好文艺的题目。

自己犯的**错误不想再提了,特别注意这题要求三个都相等时也计入统计,所以就特别处理一下。

裸的三位偏序,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 }

 

posted @ 2017-12-21 17:54  大奕哥&VANE  阅读(179)  评论(0编辑  收藏  举报