题意:给出n个01串,m个询问,每次询问将2个串拼接起来,然后求一个最大的k,使得长度为k的01串全部是这2个串的子串(一共2^k)个,拼接的新串可以作为后面询问的原串再次拼接
思路:直接暴力做,每次讲串拼接起来成为新串,然后枚举k,找到最大的可行的k,有一个地方可以记忆化,就是比如a 和b 拼接,如果a的答案是ka,那么a b拼接至少是ka,这样做下去有一个问题,就是空间会炸,因为如果每次自己和自己拼接,那么最大可能是100^100的长度,所以这里用一个技巧,就是每次计算完答案后,如果长度大于2000, 把中间的去掉,只保留前后各1000个字符,因为,比如a的答案为ka, b的答案为kb,若拼接后答案小于ka 或者kb,那么不需要计算,直接可以记忆化得到答案,若拼接后答案大于ka和kb,那么答案一定不是单独在a或者b里面,一定是跨越了a和b的,因为如果在a和b里面就不可能比ka kb大,而跨越a b的长度为1000的部分是完全正确没有缺少或者被删除的,因为输入字符串最多为100个,所以,长度很大的化必然有很多完全重复的部分,1000已经足够大,可以保留到基本上所有出现过的的01串
AC代码:
#include "iostream" #include "iomanip" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #pragma comment(linker, "/STACK:102400000,102400000") #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a,x) memset(a,x,sizeof(a)) #define step(x) fixed<< setprecision(x)<< #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define ll long long #define endl (" ") #define ft first #define sd second #define lrt (rt<<1) #define rrt (rt<<1|1) using namespace std; const ll mod=1e9+7; const ll INF = 1e18+1LL; const int inf = 1e9+1e8; const double PI=acos(-1.0); const int N=1e5+100; int K[205],k,a,b,n,m; vector<int> vex[205]; string s[205],ss; char sx[205]; void fun0(int x, int t){ int p=0; while(x>0){ sx[p++]=(x&1)+'0'; x>>=1; } for(int i=p; i<t; ++i) sx[i]='0'; sx[t]='