• bzoj3295 [Cqoi2011]动态逆序对


      cdq分治。

      代码

    #include<cstdio>
    #include<algorithm>
    #define N 200010
    #define lb(x) (x&-x)
    using namespace std;
    int n,b[N],a[N],id[N],ans[N],i,m,L[N],R[N],c[N];
    long long Ans;
    struct g{
        int v,typ;
    }v[N];
    bool cmp(g a,g b)
    {
        return a.v<b.v;
    }
    void cc(int x,int w)
    {
        while (x<=n)
        {
            c[x]+=w;
            x+=lb(x);
        }
    }
    int sum(int x)
    {
        int ans=0;
        while (x)
        {
            ans+=c[x];
            x-=lb(x);
        }
        return ans;
    }
    void solve(int l,int r)
    {
        int m,i,tot=0,cnt=0;
        if (l>=r) return;
        m=(l+r)>>1;
        for (i=l;i<=m;i++)
        {
            v[++tot].typ=0;
            v[tot].v=b[i];
        }
        for (i=m+1;i<=r;i++)
        {
            v[++tot].typ=i;
            v[tot].v=b[i];
        }
        sort(v+1,v+1+tot,cmp);
        for (i=tot;i>=1;i--)
        if (v[i].typ) 
        ans[v[i].typ]+=sum(id[v[i].v]);
        else
        cc(id[v[i].v],1);
        for (i=1;i<=tot;i++)
        if (v[i].typ==0)
        cc(id[v[i].v],-1);
        
        for (i=1;i<=tot;i++)
        if (v[i].typ) 
        ans[v[i].typ]+=cnt-sum(id[v[i].v]);
        else
        {
            cnt++;
            cc(id[v[i].v],1);
        }
        for (i=1;i<=tot;i++)
        if (v[i].typ==0)
        cc(id[v[i].v],-1);
        
        solve(l,m);
        solve(m+1,r);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            id[a[i]]=i;
        }
        for (i=1;i<=n;i++)
        {
            L[i]=sum(n)-sum(a[i]);
            cc(a[i],1);
        }
        for (i=1;i<=n;i++)
        c[i]=0;
        for (i=n;i>=1;i--)
        {
            R[i]=sum(a[i]);
            cc(a[i],1);
        }
        for (i=1;i<=n;i++)
        c[i]=0;
        for (i=1;i<=n;i++)
            Ans=Ans+L[i];
        for (i=1;i<=m;i++)
            scanf("%d",&b[i]);
        solve(1,m);
        for (i=1;i<=m;i++)
        {
            printf("%lld
    ",Ans);
            Ans=Ans-L[id[b[i]]]-R[id[b[i]]]+ans[i];
        }    
    }
  • 相关阅读:
    sqlplus中var和print的使用
    sqlplus中break命令的使用
    android之OptionsMenu
    android之TabHost(下)
    android之TabHost(上)
    android之dialog
    android之listview
    android开发事件监听
    决策树ID3算法示例
    回溯法-设置碉堡
  • 原文地址:https://www.cnblogs.com/fzmh/p/5396031.html
Copyright © 2020-2023  润新知