zoukankan      html  css  js  c++  java
  • [noip2013]火柴排队

    涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:

    ::点击图片在新窗口中打开::

    ,其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度。
    每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。

    题解:

    用"显然"证明法可知,当ai与bi在A和B中的rank相等时,S最小;

    于是我们就可以把a数组映射成有序的,再把b数组按照a数组的映射方法映射,这样就可以按逆序对来做;

    求逆序对还是按归并排序来做吧,树状数组做法虽然简洁,但需要离散;

    代码:

    老版本:

    #01: Accepted (15ms, 67624KB)
    #02: Accepted (15ms, 67624KB)
    #03: Accepted (15ms, 67624KB)
    #04: Accepted (15ms, 67624KB)
    #05: Accepted (15ms, 67624KB)
    #06: Accepted (31ms, 67624KB)
    #07: Accepted (15ms, 67624KB)
    #08: Accepted (31ms, 67624KB)
    #09: Accepted (62ms, 67624KB)
    #10: Accepted (125ms, 67624KB)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<iomanip>
    #include<map>
    #include<set>
    #include<vector>
    #include<ctime>
    #include<cmath>
    #define LL long long 
    using namespace std;
    #define LL long long 
    #define up(i,j,n) for(int i=(j);(i)<=(n);(i)++)
    #define max(x,y) ((x)<(y)?(y):(x))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define FILE "1"
    const int maxn=101000,mod=99999997;
    int n;
    int a[maxn],b[maxn],q[maxn],c[maxn];
    int read(){
        bool flag=0;char ch=getchar();int x=0;
        while(ch>'9'||ch<'0'){if(ch=='-')flag=1;ch=getchar();}
        while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
        return flag?-x:x;
    }
    int d[maxn];
    int lowbit(int x){return x&-x;}
    void add(int x){while(x<=n){d[x]+=1;x+=lowbit(x);}}
    LL get(int x){LL ans=0;while(x>0)ans=(ans+d[x])%mod,x-=lowbit(x);return ans;}
    void getni(){
        LL ans=0;
        up(i,1,n){
            ans=(ans+get(n+1-c[i]))%mod;
            add(n+1-c[i]);
        }
        printf("%I64d
    ",ans);
    }
    const int step=7,tail=4000000,head=0;
    struct hash{
        pair<int,int> t[5000000];
        int find(int x,int d){
            int y=x%mod*3%mod*5%tail;
            while(t[y].first!=x&&t[y].first!=0){
                y+=step;
                if(y>tail)y-=tail;
            }
            if(t[y].first==0){
                t[y].second=d;
                t[y].first=x;
                return y;
            }
            else return t[y].second;
        }
    }t,p;//手写map,用hash实现map的部分功能
    int k[maxn];
    void init(){
        scanf("%d",&n);
        up(i,1,n)q[i]=a[i]=read(),t.find(a[i],i);
        up(i,1,n)k[i]=b[i]=read();
        sort(q+1,q+n+1);
        sort(k+1,k+n+1);
        up(i,1,n)p.find(k[i],i);
        up(i,1,n)c[t.find(q[p.find(b[i],0)],0)]=i;
        getni();
    }
    int main(){
        init();
        return 0;
    }
    View Code

     新版本:

    #01: Accepted (0ms, 5000KB)
    #02: Accepted (0ms, 5000KB)
    #03: Accepted (0ms, 5000KB)
    #04: Accepted (0ms, 5000KB)
    #05: Accepted (0ms, 5000KB)
    #06: Accepted (0ms, 5000KB)
    #07: Accepted (0ms, 5000KB)
    #08: Accepted (15ms, 5000KB)
    #09: Accepted (31ms, 5000KB)
    #10: Accepted (46ms, 5000KB)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<iomanip>
    #include<map>
    #include<set>
    #include<vector>
    #include<ctime>
    #include<cmath>
    #define LL long long 
    using namespace std;
    #define LL long long 
    #define up(i,j,n) for(int i=(j);(i)<=(n);(i)++)
    #define max(x,y) ((x)<(y)?(y):(x))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define FILE "1"
    const int maxn=101000,mod=99999997;
    int n,c[maxn];
    struct node{
        int num,id;
        bool operator<(const node& b)const{return num<b.num;}
    }a[maxn],b[maxn];
    int read(){
        bool flag=0;char ch=getchar();int x=0;
        while(ch>'9'||ch<'0'){if(ch=='-')flag=1;ch=getchar();}
        while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
        return flag?-x:x;
    }
    int d[maxn];
    int lowbit(int x){return x&-x;}
    void add(int x){while(x<=n){d[x]+=1;x+=lowbit(x);}}
    LL get(int x){LL ans=0;while(x>0)ans=(ans+d[x])%mod,x-=lowbit(x);return ans;}
    void getni(){
        LL ans=0;
        up(i,1,n){
            ans=(ans+get(n+1-c[i]))%mod;
            add(n+1-c[i]);
        }
        printf("%I64d
    ",ans);
    }
    void init(){
        scanf("%d",&n);
        up(i,1,n)a[i].num=read(),a[i].id=i;
        up(i,1,n)b[i].num=read(),b[i].id=i;
        sort(a+1,a+n+1);sort(b+1,b+n+1);
        up(i,1,n)c[a[i].id]=b[i].id;
        getni();
    }
    int main(){
        init();
        return 0;
    }
    View Code

    主要是第一个版本映射写的太辣鸡了点;

  • 相关阅读:
    oracle,sql server count函数 存储过程 判断 行数 注意事项
    js 跨域访问 获取验证码图片 获取header 自定义属性
    开发作中常用,实用工具推荐!
    phpcms
    php基础
    jQuery , js 写选项卡
    js, jquery实现全选,反选
    jQuery选择器
    学习jQuery
    javascript 与 java继承问题
  • 原文地址:https://www.cnblogs.com/chadinblog/p/5943839.html
Copyright © 2011-2022 走看看