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

    P1966 火柴排队

    题目描述
    涵涵有两盒火柴,每盒装有 nn 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ¥(sum (a_i-b_i)^2∑(a i ​ −b i ​ ) 2)

    其中 a_i

    ​ 表示第一列火柴中第 i 个火柴的高度, b_i

    ​ 表示第二列火柴中第 i 个火柴的高度。

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

    输入输出格式
    输入格式:
    共三行,第一行包含一个整数 nn ,表示每盒中火柴的数目。

    第二行有 n n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。

    第三行有 nn 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。

    输出格式:
    一个整数,表示最少交换次数对 99,999,99799,999,997 取模的结果。


    很经典的一道题, 以前就做过了, 今天培训讲到, 写博客复习一下

    首先我们可以 瞎j8猜 判断出: 当两个火柴序列在本序列内排序同另一个序列相同, 则答案最优。 什么意思呢?就是当在第一个序列中, 排名为 (x) 的火柴棒排在第 (p) 个, 而在第二个序列中排名为 (x) 的火柴棒也排在第 (p) 个, 当每一个火柴棒满足这一条件时, 得出的和最小, 显然转化为逆序对的求解问题。

    在一般的逆序对问题中, 通常只给出一个序列, 直接求逆序对的个数。 但是事实上, 这不是等价于给你两个序列, 一个无序, 另一个有序 (1, 2, 3, 4..., n) 求解将第一个排序成为有序的那个的逆序对个数吗? 换句话说, 本题也是求解逆序对, 只是已经给出排序的依据(可以A为依据排序B, 亦可以以B为依据排序A), 而不是普通的有序序列。

    所以我们先对(A,B)按照值的大小排序, 以有序序列为桥梁, 找出 (A,B) 的对应关系(这个过程中可以离散化一下), 再(按照 (A) 的原始顺序)排序回来, 就得到了(以 (A) 为依据)的 (B) 的排序顺序了

    树状数组求解逆序对即可

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define lowbit(i) ((i) & (-i))
    typedef long long LL;
    using namespace std;
    LL RD(){
        LL out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const LL maxn = 10000019,M = 99999997;
    LL num;
    LL c[maxn];
    void update(LL x,LL val){for(LL i = x;i < maxn;i += lowbit(i))c[i] += val;}
    LL getsum(LL x){
        LL ans = 0;
        for(LL i = x;i > 0;i -= lowbit(i))ans += c[i];
        return ans;
        }
    struct A{
        LL val,index;
        }a[maxn],b[maxn],I[maxn];
    bool cmp1(A a,A b){return a.val < b.val;}
    bool cmp2(A a,A b){return a.index > b.index;}
    int main(){
        num = RD();
        for(LL i = 1;i <= num;i++)a[i].val = RD(),a[i].index = i;
        for(LL i = 1;i <= num;i++)b[i].val = RD(),b[i].index = i;
        sort(a + 1,a + 1 + num,cmp1);
        sort(b + 1,b + 1 + num,cmp1);
        for(LL i = 1;i <= num;i++)I[i].val = a[i].index,I[i].index = b[i].index;
        sort(I + 1,I + 1 + num,cmp2);
        LL ans = 0;
        for(LL i = 1;i <= num;i++){
            update(I[i].val,1);
            ans += getsum(I[i].val - 1);
            ans %= M;
            }
        printf("%lld
    ",ans);
        return 0;
        }
    
  • 相关阅读:
    SAP扫盲系列之二:SAP ABAP应用服务器的组成部分
    SAP扫盲系列之一:什么是SAP系统和应用服务器
    SAP CRM中间件下载时,为什么有时候会生成一个奇怪的BDOC容器
    SAP Cloud for Customer ABSL的一些优化
    How to test Delta download in CRM Side
    SAP CRM中间件下载时数据库表CRMATAB为空的处理方法
    如何关闭SAP CRM中间件的delta download方式
    SAP CRM Fiori应用冗余round trip的原因分析
    SAP CRM WebClient UI上以html格式显示note的问题讨论
    微信授权登录
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9323495.html
Copyright © 2011-2022 走看看