zoukankan      html  css  js  c++  java
  • [AtCoder]NIKKEI Programming Contest 2019-2 C

    题目链接:

    题目链接

    题意简述:

    给定两个长度均为$n$的序列$A,B$

    定义一次操作为:交换$A_i, A_j$,其中$i in [1, n], j in [1, n]$且$i neq j$

    问是否能使用小于等于$n - 2$次操作,使得:$forall i in [1, n]$,总有$A_i leq B_i$?

    其中$1 le n le 100, 000$

    简要做法:

    特别巧妙的一道题。

    设排序后的数组分别为$A’$和$B’$,那么:

    如果$exists i, j$满足$A’_i > B’_j$,那么一定是不可行的;

    如果$exists i$满足$A’_i le B’_{i+1}$,那么一定是可行的。

    排除了上述两种特殊情况后,考虑构建一个图:

    对于$A$中的任意一个数$A_i$,设其在$A’$中的排名为$rank(A, i)$,

    那么连一条$A_i to B_j$的边,其中$j$满足:$rank(B, j) = rank(A, i)$

    显然这样会形成至少一个环,其中每条边$A_i to B_j$表示应该交换$A_i, A_j$

    环的总长度就为交换次数,

    那么如果只有一个环,就有$n - 1$条边,无法满足题意;

    如果有多于一个的环,就有小于等于$n - 2$条边,满足题意。

    参考代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68

    #define ll long long
    #define rgi register int
    #define rgl register long long
    #define il inline

    const int N = 2e5 + 10;

    int n, tot, cnt, num[N], nxt[N], vis[N];
    int a[N], sortA[N], rankA[N];
    int b[N], sortB[N], posB[N];

    il int () {
    rgi x = 0, f = 0, ch;
    while(!isdigit(ch = getchar())) f |= ch == 大专栏  [AtCoder]NIKKEI Programming Contest 2019-2 C - Swapsn class="string">'-';
    while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    return f ? -x : x;
    }

    int main() {
    n = read();
    for(rgi i = 1; i <= n; ++i) a[i] = num[++tot] = read();
    for(rgi i = 1; i <= n; ++i) b[i] = num[++tot] = read();

    std::sort(num + 1, num + tot + 1);
    tot = std::unique(num + 1, num + tot + 1) - (num + 1);
    for(rgi i = 1; i <= n; ++i) a[i] = std::lower_bound(num + 1, num + tot + 1, a[i]) - (num + 1) + 1;
    for(rgi i = 1; i <= n; ++i) b[i] = std::lower_bound(num + 1, num + tot + 1, b[i]) - (num + 1) + 1;


    for(rgi i = 1; i <= n; ++i) sortA[i] = a[i];
    for(rgi i = 1; i <= n; ++i) sortB[i] = b[i];
    std::sort(sortA + 1, sortA + n + 1);
    std::sort(sortB + 1, sortB + n + 1);
    //Smallest Permutation

    for(rgi i = 1; i <= n; ++i) if(sortA[i] > sortB[i]) {
    puts("No");
    return 0;
    }
    for(rgi i = 1; i <= n - 1; ++i) if(sortA[i + 1] <= sortB[i]) {
    puts("Yes");
    return 0;
    }
    //Exclusion

    for(rgi i = 1; i <= n; ++i) posB[b[i]] = i;
    //pos in b[]

    for(rgi i = 1; i <= n; ++i) rankA[sortA[i]] = i;
    //rank in a[]

    for(rgi i = 1; i <= n; ++i) nxt[i] = posB[sortB[rankA[a[i]]]];
    //Add edges

    for(rgi i = 1; i <= n; ++i) if(!vis[i]) {
    int cur = i;
    do {
    vis[cur] = 1;
    cur = nxt[cur];
    } while(!vis[cur]);
    cnt++;
    }

    puts(cnt == 1 ? "No" : "Yes");

    return 0;
    }
  • 相关阅读:
    SQL Server复制情况下的高可用方案(一)镜像+复制
    sqlserver数据库镜像运行模式
    普通PC机支持内存128G,单条32G内存
    ICSharpCode.SharpZipLib 压缩、解压文件 附源码
    利用SharpZipLib进行字符串的压缩和解压缩
    SQL Server常见数据类型介绍
    .net中压缩和解压缩的处理
    solr字段压缩属性compressed新版本已经移除
    solr schema.xml Field属性详解
    Altmetric
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12409397.html
Copyright © 2011-2022 走看看