• 国家集训队 排队


    题目描述

    题解:

    将交换看作两个插入+两个删除。

    然后CDQ。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 30050
    #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,cnt,stu[N];
    struct Pair
    {
        int x,id;
    }tk[N];
    bool cmp(Pair a,Pair b)
    {
        return a.x<b.x;
    }
    struct node
    {
        int pos,val,id,wgt;
        node(){}
        node(int p,int v,int i,int w):pos(p),val(v),id(i),wgt(w){}
    }p[N],tmp[N];
    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(i<=mid&&p[i].pos<=p[j].pos)
            {
                tmp[k]=p[i];
                i++,k++;
            }
            while(j<=r&&p[i].pos>p[j].pos)
            {
                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];
    }
    int f[N];
    void up(int x,int d)
    {
        if(!x)return ;
        while(x<N)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;
    }
    int k = 0;
    ll ans[N];
    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[j].pos<=p[i].pos)up(p[j].val,p[j].wgt),j++;
            ans[p[i].id]+=p[i].wgt*(down(k)-down(p[i].val));
        }
        for(j=j-1;j>=l;j--)up(p[j].val,-p[j].wgt);
        j=mid;
        for(i=r;i>mid;i--)
        {
            while(j>=l&&p[j].pos>=p[i].pos)up(p[j].val,p[j].wgt),j--;
            ans[p[i].id]+=p[i].wgt*down(p[i].val-1);
        }
        for(j=j+1;j<=mid;j++)up(p[j].val,-p[j].wgt);
    }
    int main()
    {
        n=rd();
        for(int x,i=1;i<=n;i++)
        {
            x=rd();
            tk[i].x=x,tk[i].id=i;
        }
        sort(tk+1,tk+n+1,cmp);
        for(int las=-1,i=1;i<=n;i++)
        {
            if(las!=tk[i].x)
            {
                las=tk[i].x;
                k++;
            }
            int j = tk[i].id;
            p[j]=node(j,k,0,1);
            stu[j] = k;
        }
        m=rd();
        for(int l,r,i=1;i<=m;i++)
        {
            l=rd(),r=rd();
            p[++n]=node(l,stu[l],i,-1);
            p[++n]=node(r,stu[r],i,-1);
            swap(stu[l],stu[r]);
            p[++n]=node(l,stu[l],i,1);
            p[++n]=node(r,stu[r],i,1);
        }
        cdq(1,n);
        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;
    }
  • 相关阅读:
    C# Array.Sort 省内排序
    Centos7开机启动tomcat8
    使用GeoWebCache发布ArcGIS切片地图(实现高清电子地图)
    获取经纬度之间距离的Java工具类
    centos7上安装rar解压软件
    GeoServer之发布Geotiff存在的问题
    $GPRMC解析
    如何在IDEA单元测试中使用Scanner获取输入内容
    GeoServer修改使用内存
    Github无法访问解决办法
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10143365.html
Copyright © 2020-2023  润新知