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

    题目传送门

    思路

    我们需要让(sum_{i=1}^{n}(a_i-b_i)^2)最小化,也就是等于(0),我们就需要让(a)序列和(b)序列所有元素对应相同。

    我们先离散化一下,然后就求最少几个操作使得(b)序列转换为(a)序列。

    我们再建立一个数组(z)

    假设我们现在有离散化后的序列 (a = {4, 3, 1, 2},b = {1, 3, 2, 4})

    我们令(z[a[i]]=b[i]),相当于以(a[i])为关键字对序列(b[i])排序。

    若序列(a)与序列(b)相等,那么此时(z[a[i]])应该等于(a[i])的,也就是(z[i] = i)

    如果我们要(a)序列与(b)序列相同,则我们需要将(z)数组进行升序排列,那交换次数就是逆序对数

    我使用的树状数组。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const long long MOD=99999997;
    int n;
    long long a[1000005],b[1000005],x[1000005],y[1000005],BIT[1000005],z[1000005];
    
    bool cmp1(int x,int y) { return a[x]<a[y]; }
    
    bool cmp2(int x,int y) { return b[x]<b[y]; }
    
    int lowbit(int x) { return x & -x; }
    
    void update(int k,int x) {
        for(int i=k;i<=n;i+=lowbit(i)) BIT[i]+=x;
        return ;
    }
    
    long long ask(int x) {
        long long ans=0;
        for(int i=x;i;i-=lowbit(i)) ans+=BIT[i];
        return ans;
    }
    
    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,cmp1);
        sort(y+1,y+n+1,cmp2);
        
        for(int i=1;i<=n;i++) z[x[i]]=y[i];
        long long ans=0;
        for(int i=1;i<=n;i++)  {
            ans+=i-ask(z[i])-1;
    	    update(z[i],1);
            ans%=MOD;
        }
        printf("%lld",ans);
        return 0;
    }
    
  • 相关阅读:
    markdown 常用语法
    markdown 转 pdf 方法
    git call failed: [git clone Could not resolve host: git.openstack.org
    从VirtualBox虚拟主机访问NAT客户机的方法
    MVC,MVP 和 MVVM 的图示
    url转义
    Python如何输出包含在对象中的中文字符?
    OpenGL
    AutoHotKey使用:空格键坏了怎么办?
    三联书社推荐好书100本
  • 原文地址:https://www.cnblogs.com/sxqn/p/13877911.html
Copyright © 2011-2022 走看看