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

    首先我们对两个数组排序,对齐每位,然后记录一个火柴对应的另一个火柴,这时我们得到了一个序列:第i根火柴需要被放到第j个位置,然后原来火柴是按升序排序的,这时需要计算逆序对,也就是交换的最少次数

    树状数组 x[i],y[i]:编号,然后z[x[i]]=y[i]:第一列第x[i]根火柴应该对应第二列第y[i]根火柴,也就是说x[i]应该被放到y[i],因为第二列要对应的火柴在y[i]

    因为最先开始火柴是按升序排列,所以求逆序对就可以了

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    typedef long long ll;
    const ll inf=99999997;
    int n;
    ll a[100010],b[100010],x[100010],y[100010],tree[600010],z[100010];
    inline bool cp1(int x,int y){return a[x]<a[y];}
    inline bool cp2(int x,int y){return b[x]<b[y];}
    inline void add(int x)
    {
        for(int t=x;t<=n;t+=(t&(-t))) tree[t]++;
    }
    inline ll sum(int x)
    {
        ll ret=0; 
        for(int t=x;t;t-=(t&(-t))) ret+=tree[t];
        return ret;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) 
        {
            scanf("%d",a+i);
            x[i]=y[i]=i;
        }
        for(int i=1;i<=n;i++) scanf("%d",b+i);
        sort(x+1,x+n+1,cp1);
        sort(y+1,y+n+1,cp2);
        for(int i=1;i<=n;i++) 
        {
            z[x[i]]=y[i];
        }
        ll ans=0;
        for(int i=1;i<=n;i++) 
        {
            ans+=i-sum(z[i])-1;add(z[i]);
            ans%=inf;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    springboot 环境搭建
    Maven工程下构建ssh项目配置
    java动态代理
    java 代理
    java反射
    Java缓存流
    java 输出流
    Java输入数据流
    使用微软 AppFabric 遇到问题
    百度文本编辑器 Ueditor for net 使用七牛存储附件的实现
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6028739.html
Copyright © 2011-2022 走看看