zoukankan      html  css  js  c++  java
  • 【数轴涂色+并查集路径压缩+加速】C. String Reconstruction

    http://codeforces.com/contest/828/problem/C

    【题意】

    【思路】

    • 因为题目保证一定有解,所有优化时间复杂度的关键就是不要重复染色,所以我们可以用并查集维护区间,把确定的点的父亲节点设为下一个点,这样访问过的点的根节点都是没访问过的点。
    • 与上一题是同样的思路,用并查集路径压缩,
    • 要求字典序最小,可以最初给每个字符都赋值'a'
    • 判断字符串最长是多少,最后加''

    【Accepted】

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<set>
     8 #include<queue>
     9 using namespace std;
    10 const int N=1e6+3;
    11 const int maxn=2*N;
    12 const int inf=0x3f3f3f3f;
    13 int fa[maxn];
    14 int n,m;
    15 int a[maxn];
    16 char str[maxn];
    17 char ans[maxn];
    18 int find(int x)
    19 {
    20     return fa[x]==x?x:fa[x]=find(fa[x]);
    21 }
    22 
    23 void init()
    24 {
    25     for(int i=0;i<maxn;i++){
    26         fa[i]=i;
    27     }
    28 }
    29 int main()
    30 {
    31     while(~scanf("%d",&n))
    32     {
    33         init();
    34         memset(ans,'a',sizeof(ans));
    35         int mmax=-inf;
    36         for(int i=0;i<n;i++)
    37         {
    38             scanf("%s%d",str,&m);
    39             int len=strlen(str);
    40             int v=-inf;
    41             for(int k=0;k<m;k++)
    42             {
    43                 scanf("%d",&a[k]);
    44                 v=max(v,a[k]);
    45             }
    46             mmax=max(mmax,v+len);
    47             for(int k=0;k<m;k++)
    48             {
    49                 int x=a[k];
    50                 int y=a[k]+len-1;
    51                 while((x=find(x))<=y)
    52                 {
    53                     ans[x]=str[x-a[k]];
    54                     fa[x]=x+1;
    55                 }
    56             }
    57         }
    58         ans[mmax]='';
    59         cout<<ans+1<<endl;
    60 
    61         
    62     }
    63     return 0;
    64 }
    View Code

    或者

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<set>
     8 #include<queue>
     9 using namespace std;
    10 const int N=1e6+3;
    11 const int maxn=2*N;
    12 const int inf=0x3f3f3f3f;
    13 int fa[maxn];
    14 int n,m;
    15 int a[maxn];
    16 char str[maxn];
    17 char ans[maxn];
    18 int find(int x)
    19 {
    20     return fa[x]==x?x:fa[x]=find(fa[x]);
    21 }
    22 
    23 void init()
    24 {
    25     for(int i=0;i<maxn;i++){
    26         fa[i]=i;
    27     }
    28 }
    29 int main()
    30 {
    31     while(~scanf("%d",&n))
    32     {
    33         init();
    34         memset(ans,'a',sizeof(ans));
    35         int mmax=-inf;
    36         for(int i=0;i<n;i++)
    37         {
    38             scanf("%s%d",str,&m);
    39             int len=strlen(str);
    40             for(int k=0;k<m;k++)
    41             {
    42                 scanf("%d",&a[k]);
    43             }
    44             mmax=max(mmax,a[m-1]+len);
    45             for(int k=0;k<m;k++)
    46             {
    47                 int x=a[k];
    48                 int y=a[k]+len-1;
    49                 while((y=find(y))!=find(x-1))
    50                 {
    51                     ans[y]=str[y-a[k]];
    52                     fa[y]=fa[y-1];
    53                 }
    54             }
    55         }
    56         ans[mmax]='';
    57         cout<<ans+1<<endl;
    58 
    59         
    60     }
    61     return 0;
    62 }
    View Code

    从右往左或从左往右合并都一样。

    一开始在数据8上T了好几回,原来并查集的find一开始没注意没有路径压缩..........

  • 相关阅读:
    KVM 重命名虚机
    甲醛了解
    递归函数,匿名函数
    函数
    zabbix监控URL
    zabbix自动发现
    vim常用命令总结
    saltstack常用命令
    zabbix监控Apache
    nginx配置详解
  • 原文地址:https://www.cnblogs.com/itcsl/p/7187045.html
Copyright © 2011-2022 走看看