D. Huge Strings
Problem Statement
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.
Input
The first line contains single integer n (1 ≤ n ≤ 100) — the number of strings. The next n lines contain strings s1 , s2 , …, sn (1 ≤ |si| ≤ 100), one per line. The total length of strings is not greater than 100.
The next line contains single integer m (1 ≤ m ≤ 100) — the number of operations. m lines follow, each of them contains two integers ai and bi (1 ≤ ai , bi ≤ n + i - 1) — the number of strings that are concatenated to form sn + i .
Output
Print m lines, each should contain one integer — the answer to the question after the corresponding operation.
Examples
Example 1
Input
5
01
10
101
11111
0
3
1 2
6 5
4 4
Output
1
2
0
Note
On the first operation, a new string “0110” is created. For k = 1 the two possible binary strings of length k are “0” and “1”, they are substrings of the new string. For k = 2 and greater there exist strings of length k that do not appear in this string (for k = 2 such string is “00”). So the answer is 1.
On the second operation the string “01100” is created. Now all strings of length k = 2 are present.
On the third operation the string “1111111111” is created. There is no zero, so the answer is 0.
题意
给你n个01串,之后给出m个操作,第i个操作把两个串接起来作为下一个串,标号为n+i,求每次操作接起来的这个串满足题意的最大的k是多少,满足题意就是长度为k的所有01串都为这个串的子串。
思路
这题首先根据长度可以推断出,k最大为20(为了保险),这样,每个串只用存他开头20个字符和结尾20个字符来进行添加子串。对于原来给出的n个串,用一个set存下他所有长度小于20的子串,合并的时候只用将两个set合并就行了。之后判断的时候就判断长度为len时set的大小是不是( 1<<len )就行了。
P.S.注意这题不能直接存整个串,因为极限数据最大的串可以到 100∗299 的长度(好像),这样不MLE就怪了……(当时我就是存了整个串,就MLE并fst了…233)
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline void readInt(int &x) {
x=0;int f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
x*=f;
}
inline void readLong(ll &x) {
x=0;int f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
x*=f;
}
/*================Header Template==============*/
set<string> have[205][25];
string s,sst[205],sen[205];
int n,q,p1,p2,ans;
int main() {
readInt(n);
for(int i=1;i<=n;i++) {
cin>>s;
int l=s.length();
for(int p=0;p<l;p++)
for(int len=1;len<=min(l-p,22);len++)
have[i][len].insert(s.substr(p,len));
if(l>=22) {
sst[i]=s.substr(0,22);
sen[i]=s.substr(l-22,22);
}
else
sst[i]=sen[i]=s;
}
readInt(q);
for(int i=1;i<=q;i++) {
cin>>p1>>p2;
s=sen[p1]+sst[p2];
int pos=sen[p1].length();
// cout<<s<<endl;
for(int l=1;l<=22;l++) {
for(set<string>::iterator en=have[p1][l].begin();en!=have[p1][l].end();en++)
have[n+i][l].insert(*en);
for(set<string>::iterator en=have[p2][l].begin();en!=have[p2][l].end();en++)
have[n+i][l].insert(*en);
}
// cout<<"!!!"<<pos<<" "<<endl;
for(int p=pos-1;p>=max(0,pos-23);p--)
for(int q=pos;q<min((int)s.length(),pos+22-(pos-p));q++) {
// cout<<p<<" "<<q<<" "<<q-p+1<<" "<<s.substr(p,q-p+1)<<endl;
have[n+i][q-p+1].insert(s.substr(p,q-p+1));
}
ans=0;
for(int l=1;l<=22;l++)
if(have[n+i][l].size()==(1<<l))
ans=max(ans,l);
printf("%d\n",ans);
s=sst[p1]+sst[p2];
sst[n+i]=s.substr(0,min(22,(int)s.length()));
s=sen[p1]+sen[p2];
sen[n+i]=s.substr(max((int)s.length()-22,0),min(22,(int)s.length()));
}
}