zoukankan      html  css  js  c++  java
  • BZOJ 3295 [Cqoi2011]动态逆序对 ——CDQ分治

    时间、位置、数字为三个属性。

    排序时间,CDQ位置,树状数组处理数字即可。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define ll long long
    #define maxn 100005
    int a[maxn],q[maxn],n,m,pos[maxn],del[maxn];
    struct Event{
        int t;//时间 
        int x;//加入的数 
        int y;//加入的位置 
    }b[maxn];
    struct Bit_Tree{
        int x[maxn];
        void add(int i,int f)
        {
            for (;i<maxn;i+=i&(-i)) x[i]+=f;
        }
        int gs(int i)
        {
            int ret=0;
            for (;i;i-=i&(-i)) ret+=x[i];
            return ret;
        }
    }BT;
     
    bool cmp1(Event a,Event b) {return a.t<b.t;}
     
    bool cmp2(Event a,Event b) {return a.y<b.y;}
     
    bool cmp3(Event a,Event b) {return a.y>b.y;}
     
    ll ans[maxn];
     
    void CDQ(int l,int r,int flag)
    {
        if (l==r) return ;
        int mid=l+r>>1;
        CDQ(l,mid,flag); CDQ(mid+1,r,flag);
        int pl=l;
        if (flag) F(i,mid+1,r)
        {
            while (b[pl].y<b[i].y&&pl<=mid) BT.add(b[pl++].x,1);
            int tmp=BT.gs(n)-BT.gs(b[i].x-1);
            ans[b[i].t]+=tmp;
        }
        else F(i,mid+1,r)
        {
            while (b[pl].y>b[i].y&&pl<=mid) BT.add(b[pl++].x,1);
            int tmp=BT.gs(b[i].x-1);
            ans[b[i].t]+=tmp;
        }
        F(i,l,pl-1) BT.add(b[i].x,-1);
        sort(b+l,b+r+1,flag?cmp2:cmp3);
    }
     
    int main()
    {
        scanf("%d%d",&n,&m);
        F(i,1,n) scanf("%d",&a[i]),pos[a[i]]=i;
        F(i,1,m)
        {
            scanf("%d",&q[i]);
            del[q[i]]=1;
            b[i].t=n-i+1;
            b[i].x=q[i];
            b[i].y=pos[q[i]];
        }
        int now=m;
        F(i,1,n)
            if (!del[i])
            {
                b[++now].t=n-now+1;
                b[now].x=i;
                b[now].y=pos[i];
            }
        sort(b+1,b+n+1,cmp1);
        CDQ(1,n,1);
        sort(b+1,b+n+1,cmp1);
        CDQ(1,n,0);
        F(i,2,n) ans[i]+=ans[i-1]; 
        D(i,n,n-m+1) printf("%lld
    ",ans[i]);
    }
    

      

  • 相关阅读:
    保留字段数组,一定要用char
    VirtualBox安装CentOS 7及其相关配置
    istringstream是支持>>一个bool的,但为什么不用?
    用vector实现一个变长数组
    C语言为什么被const声明的变量不是一个常量表达式
    不咬文嚼字的理由
    int变量赋值给char变量的本质
    #include <> 和 #include "" 的区别
    C++中匿名对象应当是一个左值
    js实战之-间断文字滑动
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6607064.html
Copyright © 2011-2022 走看看