[Codeforces Round #438][Codeforces 868D. Huge Strings]
Posted deaphets
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Codeforces Round #438][Codeforces 868D. Huge Strings]相关的知识,希望对你有一定的参考价值。
题目链接:868D - Huge Strings
题目大意:有(n)个字符串,(m)次操作,每次操作把两个字符串拼在一起,并询问这个新串的价值。定义一个新串的价值(k)为:最大的(k),使得这个新串包含所有长度为(k)的01串(这样的字符串有(2^k)个)
题解:首先来证明对于任何的串,这个(k)的值不会超过9
若(k=10),由所有字符串的长度总和不超过100,因此在初始的(n)个串里,互不相同的长度为(k)的子串不超过100个。又由于每次连接最多能产生9个新的长度为(k)的子串(即横跨两个字符串之间的子串),因此互不相同的子串个数最多为(9 cdot100+100<2^k),故(k<10)
接下来就只需要记录每个字符串的前缀,后缀以及长度为(k)的子串有哪些就好了。
#include<bits/stdc++.h> using namespace std; #define N 101 int n,m,a,b; struct rua { string st,ed; set<int>has[10]; bool check(int k) { for(int i=0;i<(1<<k);i++) if(!has[k].count(i))return false; return true; } int ans() { for(int k=9;k>0;k--) if(check(k))return k; return 0; } rua connect(rua nxt) { rua res=nxt; res.st=st; if(st.size()<9) res.st=st+nxt.st.substr(0,min(nxt.st.size(),9-st.size())); int cpy_len=min(ed.size(),9-nxt.ed.size()); if(nxt.ed.size()<9) res.ed=ed.substr(ed.size()-cpy_len,cpy_len)+nxt.ed; for(int k=1;k<=9;k++) for(auto i:has[k])res.has[k].insert(i); string tmp=ed+nxt.st; int len=tmp.size(); for(int i=0;i<len;i++) { int value=0; for(int d=0;d<9 && i+d<len;d++) value=value*2+tmp[i+d]-‘0‘, res.has[d+1].insert(value); } return res; } }f[2*N]; string s; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>s; int len=s.size(); for(int j=0;j<len;j++) { int value=0; for(int d=0;d<9 && j+d<len;d++) value=value*2+s[j+d]-‘0‘, f[i].has[d+1].insert(value); } int cpy_len=min(9,len); f[i].st=s.substr(0,cpy_len); f[i].ed=s.substr(len-cpy_len,cpy_len); } scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); f[n+i]=f[a].connect(f[b]); printf("%d ",f[n+i].ans()); } }
以上是关于[Codeforces Round #438][Codeforces 868D. Huge Strings]的主要内容,如果未能解决你的问题,请参考以下文章
[Codeforces Round #438][Codeforces 868C. Qualification Rounds]
Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined) A,B,C真的菜·(代