bzoj 3295: [Cqoi2011]动态逆序对

2016-06-22

这个题本想昨天晚上做来,但昨晚狂风大作,暴雨倾盆(听说我们学校最落后的一堵墙都被吹到了),停电了,我只能无聊的瞭望了教学楼一晚上。。。。。。

这个题把删除看成插入的话,插入一个点 新增逆序对就是比他早插入的,位置靠前,数比他大或 位置靠后,数比他小。那这就是个三维偏序集,可以用CDQ搞搞了。

这个题也能用树套树,树状数组归并排序做(以后有时间要写一写,恐怕是没可能了%>_<%)。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<queue>
  7 #define ll long long
  8 #define M 1000009
  9 using namespace std;
 10 ll read()
 11 {
 12     char ch=getchar();
 13     ll x=0,f=1;
 14     for(;ch<'0'||ch>'9';ch=getchar())
 15       if(ch=='-')
 16         f=-1;
 17     for(;ch>='0'&&ch<='9';ch=getchar())
 18       x=x*10+ch-'0';
 19     return x*f;
 20 }
 21 int n,m;
 22 ll ans[M],shu[M];
 23 bool f[M];
 24 struct data
 25 {
 26     int A,B,C;
 27 }a[M];
 28 bool cmp(data a1,data a2)
 29 {
 30     return a1.A>a2.A;
 31 }
 32 bool cmp1(data a1,data a2)
 33 {
 34     return a1.B<a2.B;
 35 }
 36 void jia(int x)
 37 {
 38     for(;x<=n;x+=x&-x)
 39       shu[x]++;
 40 }
 41 void jian(int x)
 42 {
 43     for(;x<=n;x+=x&-x)
 44       shu[x]--;
 45 }
 46 int query(int x)
 47 {
 48     int sum=0;
 49     for(;x;x-=x&-x)  
 50       sum+=shu[x];
 51     return sum;
 52 }
 53 void cdq(int l,int r)
 54 {
 55     if(l==r)
 56       return;
 57     int mid=(l+r)>>1;
 58     cdq(l,mid);
 59     cdq(mid+1,r);
 60     sort(a+l,a+mid+1,cmp1);
 61     sort(a+mid+1,a+r+1,cmp1);
 62     int l1=l,l2=mid+1;
 63     for(;l1<=mid&&l2<=r;)
 64       if(a[l1].B<a[l2].B)
 65         {
 66           jia(n-a[l1].C+1);
 67           l1++;
 68         }
 69       else
 70         {
 71             ans[a[l2].A]+=query(n-a[l2].C+1);
 72             l2++;
 73         }
 74     for(int i=l2;i<=r;i++)
 75       ans[a[i].A]+=query(n-a[i].C+1);
 76     for(int i=l;i<l1;i++)
 77       jian(n-a[i].C+1);
 78 }
 79 int main()
 80 {
 81     n=read();
 82     m=read();
 83     for(int i=1;i<=n;i++)
 84       {
 85           int a1=read();
 86           a[a1].B=i;
 87           a[a1].C=a1;
 88       }
 89     for(int i=1;i<=m;i++)
 90       {
 91           int a1=read();
 92           f[a1]=1;
 93           a[a1].A=i;
 94       }
 95     int y=0;
 96     for(int i=1;i<=n;i++)
 97       if(!f[i])
 98         {
 99           ++y;
100           a[i].A=m+y;
101         }
102     sort(a+1,a+n+1,cmp);
103     cdq(1,n);
104     for(int i=1;i<=n;i++)
105       {
106           a[i].B=n-a[i].B+1;
107         a[i].C=n-a[i].C+1;
108       }
109     sort(a+1,a+n+1,cmp);
110     cdq(1,n);
111     for(int i=n;i;i--)
112       ans[i]+=ans[i+1];
113     for(int i=1;i<=m;i++)
114       printf("%lld\n",ans[i]);
115     return 0;
116 }

 

posted @ 2016-06-22 08:23  xiw5  阅读(127)  评论(0编辑  收藏  举报