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;
    }
  • 相关阅读:
    django rest framework renderer
    django集成celery
    Celery
    ajax csrftoken
    验证码刷新、倒计时
    C++ const关键字以及static关键字
    git 查看当前仓库地址以及设置新的仓库地址
    C++ explicit关键字
    SSD训练网络参数计算
    C++ opencv调用resize修改插值方式遇到的坑
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6028739.html
Copyright © 2011-2022 走看看