Codeforces Round #438 (Div. 1 + Div. 2 combined) D. Huge Strings

来源:互联网 发布:留学cv 知乎 编辑:程序博客网 时间:2024/06/07 23:34

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 stringss1, 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.注意这题不能直接存整个串,因为极限数据最大的串可以到100299的长度(好像),这样不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()));    }}
阅读全文
1 0
原创粉丝点击