Codeforces 868 D. Huge Strings (二分+随机+SAM)
2017-10-06 10:05
489 查看
Description
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 abd 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.Example input
5 01 10 101 11111 0 3 1 2 6 5 4 4
Example output
1 2 0
题意
一个字符串最多可以包含几位二进制数的所有组合。思路
以下做法属于旁门左道,二分 + 随机 + SAM 成功水过数据。首先利用这个字符串建立后缀自动机,然后二分答案 k ,对于每一个 k 我们最多测试 1000 种组合,其中每一种组合都是随机生成的,然后在自动机中查找是否包含该子串。
因为初始的字符串可能是由某两个子串连接得到的,如果不做限制的话该串最长可以到达 2100×100 位。
我们假设当前字符串为 s ,它是由 a,b 连接得到的,假如 len(s)>1000 , s=s.substr(0,500)+s.substr(len(s)−500,500) ,因为概率。。。
最终的结果为 max(test(a),test(b),test(s)) 。
AC 代码
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5+10; const int maxm = 210; typedef long long LL; LL ans, K; struct SAM { int ch[maxn][2]; int pre[maxn], step[maxn]; int last, id; int nu[maxn]; void init() { last = id = 0; memset(ch[0], -1, sizeof(ch[0])); pre[0] = -1; step[0] = 0; } void insert(int c) { int p = last, np = ++id; step[np] = step[p] + 1; memset(ch[np], -1, sizeof(ch[np])); while (p != -1 && ch[p][c] == -1) ch[p][c] = np, p = pre[p]; if (p == -1) pre[np] = 0; else { int q = ch[p][c]; if (step[q] != step[p] + 1) { int nq = ++id; memcpy(ch[nq], ch[q], sizeof(ch[q])); step[nq] = step[p] + 1; pre[nq] = pre[q]; pre[np] = pre[q] = nq; while (p != -1 && ch[p][c] == q) ch[p][c] = nq, p = pre[p]; } else pre[np] = q; } last = np; } } sam; unordered_map<string,bool> sk; bitset<64> ss; bool judge(const int &mid) { sk.clear(); LL maxx = min(1LL<<(mid+5),1000LL); for(int i=0; i<maxx; i++) { ss = rand(); string now = ss.to_string(); if(sk[now])continue; sk[now] = true; int id = 0; for(int j=0; j<mid; j++) { if(sam.ch[id][ss[j]]==-1) return false; id = sam.ch[id][ss[j]]; } } return true; } string s[maxm]; int n,m; int dp[maxm]; int solve(int id) { sam.init(); int len = s[id].length(); for(int i=0; i<len; i++) sam.insert(s[id][i]-'0'); int low = 0,high = 20; while(true) { int mid = (low+high)>>1; if(mid==low) { if(judge(high)) low = high; break; } if(judge(mid)) low = mid; else high = mid-1; } return low; } int main() { srand((unsigned)time(NULL)); ios::sync_with_stdio(false); cin.tie(0); cin>>n; for(int i=1; i<=n; i++) cin>>s[i]; cin>>m; for(int i=n+1; i<=n+m; i++) { int a,b; cin>>a>>b; s[i] = s[a]+s[b]; if(s[i].length()>1000) s[i] = s[i].substr(0,500) + s[i].substr(s[i].length()-500,500); dp[i] = max({dp[a],dp[b],solve(i)}); cout<<dp[i]<<endl; } return 0; }
相关文章推荐
- Codeforces 868D (Codeforces Round #438 D) Huge Strings 分治+哈希
- Codeforces 868 D Huge String
- Codeforces 703C Chris and Road 二分、思考
- CodeForces 378C - Road to Cinema(二分)
- codeforces-729【思维】【二分】
- CodeForces 225B Well-known Numbers(二分)
- CodeForces 660F Bear and Bowling 4(斜率DP+二分)
- Codeforces 920G(二分+容斥)
- Codeforces 706B Interesting drink 【二分】
- Codeforces 782B 二分搜索
- Codeforces 535C : Tavas and Karafs(二分)
- CodeForces 165B Burning Midnight Oil(二分)
- Two strings CodeForces - 762C(二分+预处理)
- Codeforces 549H. Degenerate Matrix 二分
- codeforces 672D 二分
- codeforces D. Multiplication Table 二分答案
- CodeForces-204E:Little Elephant and Strings (广义后缀自动机求出现次数)
- 【二分+交互】codeforces B. Glad to see you!
- CodeForces - 609D Gadgets for dollars and pounds(二分)
- codeforces_607A. Chain Reaction(二分+简单dp)