• Codeforces Round #438 D. Huge Strings


    Description

    You are given n strings s1, s2, ..., sn consisting of characters 0 and 1. m operations are performed, on each of them you concatenate two existing strings into a new one. On the i-th operation the concatenation saisbi is saved into a new string sn + i (the operations are numbered starting from 1). After each operation you need to find the maximum positive integer k such that all possible strings consisting of 0 and 1 of length k (there are 2k such strings) are substrings of the new string. If there is no such k, print 0.

    解题报告

    这题对于合并的两个串的操作,新串对两个合并的串连边,由于每一次长度最多翻一倍,也就是最长为 (2^{100}) ,所以 (k) 长度也不超过100,所以可以分治处理,那么新串就可以只存新串的长度为100的部分,也就是说 左边部分的后k个和右边部分的前k个需要单独算贡献,内部的贡献直接分治处理,枚举 (k),然后直接哈希字符串判断出现次数,并记录串的个数是否等于 (2^k) 即可

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <map>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=205;
    string s[N][2];int len[N],n,ls[N],rs[N],m,tot=0;
    map<string,int>re;bool vis[N];
    void dfs(int x,int k){
       if(vis[x])return ;vis[x]=true;
       if(!rs[x]){
          for(int i=0;i+k<=len[x];i++){
             string w=s[x][0].substr(i,k);
             if(!re[w]){
                re[w]++;tot++;
             }
          }
          return ;
       }
       string S=s[ls[x]][1]+s[rs[x]][0];
       int li=S.size();
       for(int i=0;i+k<=li;i++){
          string w=S.substr(i,k);
          if(!re[w]){
             re[w]++;tot++;
          }
       }
       dfs(ls[x],k);dfs(rs[x],k);
    }
    bool check(int k,int x){
       memset(vis,0,sizeof(vis));re.clear();tot=0;
       dfs(x,k);
       if(tot==(1<<k))return true;
       return false;
    }
    void work()
    {
       scanf("%d",&n);
       for(int i=1;i<=n;i++){
          cin>>s[i][0];
          s[i][1]=s[i][0];
          ls[i]=rs[i]=0;
          len[i]=s[i][0].size();
       }
       scanf("%d",&m);
       for(int i=n+1;i<=n+m;i++){
          scanf("%d%d",&ls[i],&rs[i]);
          s[i][0]=s[ls[i]][0];
          if(len[ls[i]]<=100)s[i][0]=s[i][0]+s[rs[i]][0];
          if(s[i][0].size()>=100)s[i][0]=s[i][0].substr(0,100);
          s[i][1]=s[ls[i]][1];
          if(len[rs[i]]<=100)s[i][1]=s[i][1]+s[rs[i]][1];
          if(s[i][1].size()>=100)s[i][1]=s[i][1].substr(s[i][1].size()-100,100);
          int k=1;
          for(k=1;k<=100;k++){
             if(!check(k,i))break;
          }
          printf("%d
    ",k-1);
       }
    }
    
    int main()
    {
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    Linux C语言错误处理
    [精彩] 关于LAN上有两个相同MAC地址的问题
    毕业一年 写给自己的警戒书
    原始套接字简单应用
    李彦宏建言创业者:准备失败 勇于创新 专注如一
    Java programming problem in linux box: Exception in thread "main" java.lang.NoClassDefFoundError
    Java新手必看之Hello World 攻略
    Android 开发简介
    libnet应用之arp包发送
    TCP/IP协议族之运输层(TCP流量控制和拥塞控制 [2])
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7630562.html
Copyright © 2020-2023  润新知