• CodeForces 828C String Reconstruction(并查集思想)


    题意:给你n个串,给你每个串在总串中开始的每个位置,问你最小字典序总串。

    思路:显然这道题有很多重复填涂的地方,那么这里的时间花费就会特别高。

    我们维护一个并查集fa,用fa[i]记录从第i位置开始第一个没填涂的位置,那每次都能跳过涂过的地方。每次填完当前格就去填find(fa[i + 1])。

    ps:一定要合并,不然超时。

    代码:

    #include<stack>
    #include<vector>
    #include<queue>
    #include<set>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    #define ull unsigned long long
    using namespace std;
    const int maxn = 1000000+5;
    const int seed = 131;
    const int MOD = 100013;
    const int INF = 0x3f3f3f3f;
    char ans[maxn*10];
    int fa[maxn*10];
    char s[maxn];
    int find(int x){
        return fa[x] == x? x : fa[x] = find(fa[x]);
    }
    int main(){
        int n,t;
        memset(ans,0,sizeof(ans));
        scanf("%d",&n);
        for(int i = 0;i < maxn * 10;i++) fa[i] = i;
        int end = 1;
        while(n--){
            scanf("%s%d",s,&t);
            int len = strlen(s);
            while(t--){
                int x;
                scanf("%d",&x);
                end = max(end,x + len - 1);
                for(int i = find(x);i <= x + len -1;i = find(i + 1)){
                    ans[i] = s[i - x];
                    int fx = find(i);
                    int fy = find(i + 1);
                    if(fx > fy)
                        fa[fy] = fx;
                    else
                        fa[fx] = fy;
                }
            }
        }
        for(int i = 1;i <= end;i++)
            if(ans[i] != 0)printf("%c",ans[i]);
            else printf("a");
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    傻逼Eclipse笔记
    Less笔记
    [转]解决WebClient或HttpWebRequest首次连接缓慢问题
    Css3图标库
    Json.Net4.5 序列化问题
    async和await
    CLR、内存分配和垃圾回收
    C#7.0新语法
    C#6.0新语法
    C#泛型详解
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9517004.html
Copyright © 2020-2023  润新知