1. 程式人生 > >Codeforces Round #438 D

Codeforces Round #438 D

esp iostream std bre mod math size clas 保留

Huge Strings

題意:給出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 ("\n") #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]=\0; } bool fun(int x, int t){ for(int i=0; i<=(1<<x)-1; ++i){ fun0(i,x); ss=sx; //cout<<i<<" "<<ss<<endl; if(s[t].find(ss)==-1) return 0; } return 1; } int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n; mem(K,-1); for(int i=1; i<=n; ++i){ cin>>s[i]; vex[i].pb(i); } cin>>m; for(int i=1; i<=m; ++i){ cin>>a>>b; k=0; s[n+i]=s[a]+s[b]; if(K[a]!=-1 || K[b]!=-1) k=max(K[a], K[b]); //cout<<k<<endl; for(int t=k+1; t<=10; ++t){ if(fun(t, n+i)) k=t; else break; } if(s[n+i].length()>2000) s[n+i]=s[n+i].substr(0,1000)+s[n+i].substr(s[n+i].length()-1000,1000); K[n+i]=k; cout<<k<<endl; } return 0; }

Codeforces Round #438 D