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\n",k-1);
}
} int main()
{
work();
return 0;
}

Codeforces Round #438 D. Huge Strings的更多相关文章

  1. Codeforces Round #438 (Div.1+Div.2) 总结

    本来兴致勃勃的想乘着这一次上紫,于是很早很早的到了机房 但是好像并没有什么用,反而rating-=47 Codeforces Round #438(Div.1+Div.2) 今天就这样匆匆的总结一下, ...

  2. [Codeforces Round #438][Codeforces 868D. Huge Strings]

    题目链接:868D - Huge Strings 题目大意:有\(n\)个字符串,\(m\)次操作,每次操作把两个字符串拼在一起,并询问这个新串的价值.定义一个新串的价值\(k\)为:最大的\(k\) ...

  3. 【Codeforces Round 438 A B C D 四个题】

    题目所在比赛的地址在这里呀 A. Bark to Unlock ·述大意:       输入一个目标串.然后输入n(1<=n<=100)个串,询问是否可以通过这些串收尾相接或者它本身拼出目 ...

  4. D. Huge Strings Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined)

    http://codeforces.com/contest/868/problem/D 优化:两个串合并 原有状态+ 第一个串的尾部&第二个串的头部的状态 串变为第一个串的头部&第二个 ...

  5. Educational Codeforces Round 12 C. Simple Strings 贪心

    C. Simple Strings 题目连接: http://www.codeforces.com/contest/665/problem/C Description zscoder loves si ...

  6. Codeforces Round #438 B. Race Against Time

    Description Have you ever tried to explain to the coordinator, why it is eight hours to the contest ...

  7. Codeforces Round #438 C. Qualification Rounds

    Description Snark and Philip are preparing the problemset for the upcoming pre-qualification round f ...

  8. Codeforces Round #313 D. Equivalent Strings(DFS)

    D. Equivalent Strings time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  9. Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined)

    A. Bark to Unlock 题目链接:http://codeforces.com/contest/868/problem/A 题目意思:密码是两个字符组成的,现在你有n个由两个字符组成的字符串 ...

随机推荐

  1. verilog学习笔记(0)

    assign赋值语句根本不允许出现在always语句块中 位于begin/end块内的多条阻塞赋值语句是串行执行的; 但是多条非阻塞赋值语句却是并行执行的,这些非阻塞赋值语句都会在其中任何一条语句执行 ...

  2. 面试必问---HashMap原理分析

    一.HashMap的原理 众所周知,HashMap是用来存储Key-Value键值对的一种集合,这个键值对也叫做Entry,而每个Entry都是存储在数组当中,因此这个数组就是HashMap的主干.H ...

  3. linux下面的打包压缩命令

    tar命令 tar [-cxtzjvfpPN] 文件与目录 ....linux下面压缩之前要把一堆文件打个包再压缩,即使只有一个文件也需要打个包.例子:tar czvf 1.tar.gz hello. ...

  4. Thinkphp框架部署步骤

    Thinkphp框架部署步骤 thinkphp框架部署起来简单,但是由于步骤较多也容易遗忘: 这是安装了集成环境后的一个www根目录结构: 然后需要在这个目录下面创建一个文件夹做项目:thinkphp ...

  5. PHP类的自动加载

    spl_autoload_register(function ($className) { require str_replace('\\', '/', $className '.php'); }) ...

  6. 1-51单片机WIFI学习(开发板介绍)

    源码链接都在后面 前面的都是介绍单独的WIFI,没有和单片机结合起来,因为做项目很少会只用WIFI模块.大多数都是WIFI模块作为中转数据的桥梁,单片机负责 数据采集,控制等等,所以自己准备出一套51 ...

  7. angular2 学习笔记 ( app initialize 初始化 )

    refer : http://stackoverflow.com/questions/39033835/angularjs2-preload-server-configuration-before-t ...

  8. 云计算(2)it 是什么

    2015年,全世界在it上面的花费达到3亿8千亿美金之多. 云数据中心:核心基础架构,云计算的物理载体,提供数据处理.存储和高性能计算支撑,包括服务器.存储.冷却.机房空间和能耗管理等. 超大规模的云 ...

  9. js中的caller属性和callee属性

    应该用"属性"来称呼caller和callee,而不是方法. caller:返回调用当前函数的函数的引用.a调用b,则返回a(a是boss,因为a把b叫过去干活了): callee ...

  10. javascript实现继承3种方式: 原型继承、借用构造函数继承、组合继承,模拟extends方法继承

    javascript中实现继承的三种方式:原型继承.借用构造函数继承.混合继承: /* js当中的继承 js中 构造函数 原型对象 实力对象的关系: 1 构造函数.prototype = 原型对象 2 ...