• CQOI2011 动态逆序对


    题目描述

    题解:

    将前n个数看作插入,后m个数仍看作删除。

    然后就是cdq分治。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 150050
    #define ll long long
    inline int rd()
    {
        int f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,m;
    struct node
    {
        int a,b,c,d;
    }p[N],tmp[N];
    int pos[N];
    ll ans[N];
    int f[N];
    void up(int x,int d)
    {
        if(!x)return ;
        while(x<=100000)f[x]+=d,x+=(x&(-x));
    }
    int down(int x)
    {
        if(!x)return 0;
        int ret = 0;
        while(x)ret+=f[x],x-=(x&(-x));
        return ret;
    }
    void Sort(int l,int r)
    {
        int mid = (l+r)>>1;
        int i=l,j=mid+1,k=l;
        while(i<=mid&&j<=r)
        {
            while(p[i].a<=p[j].a&&i<=mid)
            {
                tmp[k]=p[i];
                i++,k++;
            }
            while(p[i].a>p[j].a&&j<=r)
            {
                tmp[k]=p[j];
                j++,k++;
            }
        }
        while(i<=mid)
        {
            tmp[k]=p[i];
            i++,k++;
        }
        while(j<=r)
        {
            tmp[k]=p[j];
            j++,k++;
        }
        for(i=l;i<=r;i++)
            p[i]=tmp[i];
    }
    void cdq(int l,int r)
    {
        if(l==r)return ;
        int mid = (l+r)>>1;
        cdq(l,mid),cdq(mid+1,r);
        Sort(l,mid),Sort(mid+1,r);
        int i,j;
        j = l;
        for(i=mid+1;i<=r;i++)
        {
            while(j<=mid&&p[i].a>=p[j].a)up(p[j].b,p[j].d),j++;
            ans[p[i].c]+=p[i].d*(down(n)-down(p[i].b));
        }
        for(j=j-1;j>=l;j--)up(p[j].b,-p[j].d);
        j = mid;
        for(i=r;i>mid;i--)
        {
            while(j>=l&&p[i].a<=p[j].a)up(p[j].b,p[j].d),j--;
            ans[p[i].c]+=p[i].d*down(p[i].b-1);
        }
        for(j=j+1;j<=mid;j++)up(p[j].b,-p[j].d);
    }
    int main()
    {
        n=rd(),m=rd();
        for(int x,i=1;i<=n;i++)
        {
            x=rd();
            p[i].a=i,p[i].b=x,p[i].c=0,p[i].d=1;
            pos[x]=i;
        }
        for(int x,j,i=1;i<=m;i++)
        {
            x=rd();j=i+n;
            p[j].a=pos[x],p[j].b=x,p[j].c=i,p[j].d=-1;
        }
        cdq(1,n+m);
        for(int i=1;i<=m;i++)ans[i]+=ans[i-1];
        for(int i=0;i<m;i++)printf("%lld
    ",ans[i]);
        return 0;
    }
    //pos val tim wgt 
  • 相关阅读:
    Camera HAL3学习
    Android GPU呈现模式分析
    Android O版本自定义日志输出目录
    Android Configstore HAL
    Ubuntu下设置adb path的方法
    Ubuntu使用技巧
    PHP学习笔记
    mysql安装
    在ubuntu中安装Python
    OS X在使用<semaphore.h>时报错
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10143340.html
Copyright © 2020-2023  润新知