• $Noip2013/Luogu1966$ 火柴排队 贪心+离散化+逆序对


    $Luogu$

    $Description$

    给定等长的$a,b$两个序列.每次可以交换一个序列中相邻两个数.求最小的交换次数使得$sum(a_i-b_i)^2$最小.

    $Sol$

    交换后的序列一定满足$a$序列中第$i$大的数和$b$序列中第$i$大的数对应.证明挺显然的就不说了,洛谷里的题解一定有的叭.然后把两个序列中的数离散化,把$b$序列中第$i$大的数转换成$a$序列中第$i$大的数所在的位置.于是问题就转化成了,$b$序列中交换多少次能变成$a$,又因为离散化后$a$序列是单增的,其实就是$1,2,3.....,n$.所以只要求此时$b$序列中的逆序对就好了.可以用归并排序或树状数组.

    $Code$

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define il inline
    #define Rg register
    #define go(i,a,b) for(Rg int i=a;i<=b;++i)
    #define yes(i,a,b) for(Rg int i=a;i>=b;--i)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define db double
    #define inf 2147483647
    using namespace std;
    il int read()
    {
        Rg int x=0,y=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x*y;
    }
    const int N=100010,mod=99999997;
    int n,c[N],d[N],e[N];
    ll as;
    struct node{int w,pos,dx;}a[N],b[N];
    il bool cmp1(node x,node y){return x.w<y.w;}
    il bool cmp2(node x,node y){return x.pos<y.pos;}
    il void lsh()
    {
        sort(a+1,a+n+1,cmp1);
        sort(b+1,b+n+1,cmp1);
        go(i,1,n)c[i]=a[i].pos;
        go(i,1,n)b[i].dx=i;
        sort(b+1,b+n+1,cmp2);
        go(i,1,n)d[i]=c[b[i].dx];
    }
    il void gb(int l,int r)
    {
        if(l==r)return;
        Rg int mid=(l+r)>>1,i=l,j=mid+1;
        gb(l,mid);gb(mid+1,r);
        go(k,l,r)
        {
            if((d[i]>d[j]&&j<=r)||i>mid)as=(as+(mid-i+1))%mod,e[k]=d[j++];
            else e[k]=d[i++];
        }
        go(k,l,r)d[k]=e[k];
    }
    int main()
    {
        n=read();
        go(i,1,n)a[i].w=read(),a[i].pos=i;
        go(i,1,n)b[i].w=read(),b[i].pos=i;
        lsh();
        gb(1,n);
        printf("%lld
    ",as);
        return 0;
    }
    View Code

     

  • 相关阅读:
    TouchAction实现连续滑动设置手势密码
    用命令方式启动、停止appium服务和app
    企业软件防火墙iptables
    磁盘分区
    docker-网络
    docker-镜像管理基础
    docker-简单操作
    docker-安装
    python-函数
    find一些常用参数的一些常用实例和一些具体用法和注意事项。
  • 原文地址:https://www.cnblogs.com/forward777/p/11414336.html
Copyright © 2020-2023  润新知