Codeforces 868D (Codeforces Round #438 D) Huge Strings 分治+哈希
来源:互联网 发布:农村淘宝服务站申请表 编辑:程序博客网 时间:2024/05/20 22:04
给你n个01串,有m次合并操作,第 i 次合并选择n个串和之前合并i-1个串当中的两个,问每次合并后的新串是否含有所有长度为k的01串,如果是,输出最大的k,否则输出0.
这道题和之前的一道树分治题目挺像。 戳这里
首先二分答案k,验证所有长度为k的不同子串是否有2^k个。对当前串进行dfs,不断将当前串分成之前的串。对于当前串,假设两个原串的所有长度为k的串都已经考虑过,那么只需要考虑新合成的那部分对于答案的影响。如果我们将长度为100的串反复翻折100次,那么它最多有100*(2^100)个字符,所以k最大为100.那么,新合成的长度为k的串,只要考虑左边原串的后k-1个字符和右边原串的前k-1个字符合并产生的结果,所以我们只要不停的dfs,每次把新合成的串加入哈希表计数,直到串不能再分,再把不能再分的串加入哈希表。这样,就验证了所有长度为k的不同子串。
对于编号固定的串,搜过一次就不需要再搜。这样,每次最多搜200个串,每个串最多哈希表计数100次,100个询问,复杂度是200*100*100=2000000. 实际上,由于哈希表的实现需要时间,最后跑了1s左右.
比赛的时候偷了个懒,哈希表用unordered_map替代了。
#include <cstdio>#include <iostream>#include <string.h>#include <string> #include <map>#include <queue>#include <deque>#include <vector>#include <set>#include <algorithm>#include <math.h>#include <cmath>#include <stack>#include <iomanip>#include <unordered_map>#define mem0(a) memset(a,0,sizeof(a))#define meminf(a) memset(a,0x3f,sizeof(a))using namespace std;typedef long long ll;typedef long double ld;typedef double db;const int maxn=105,inf=0x3f3f3f3f; const ll llinf=0x3f3f3f3f3f3f3f3f; const ld pi=acos(-1.0L);string a[maxn*2][2];int lc[maxn*2],rc[maxn*2],len[maxn*2];bool visit[maxn * 2];unordered_map<string,int> mp;ll cnt;void dfs(int now,int k) {if (visit[now]) return;visit[now] = 1;if (lc[now]==0) {for (int i=0;i+k<=len[now];i++) {string s=a[now][0].substr(i,k);//cout << s << endl; if (mp[s]==0) { mp[s]++;cnt++; } }} else {string s=a[lc[now]][1]+a[rc[now]][0];int le=s.length();for (int i=0;i+k<=le;i++) {string t=s.substr(i,k);//cout << t << endl; if (mp[t]==0) { mp[t]++;cnt++; } }dfs(lc[now], k); dfs(rc[now], k);}}bool check(int k,int n) {mp.clear();mem0(visit);cnt=0;dfs(n,k);if (cnt==(1<<k)) return true; else return false;}int main() {int n,m,i,j,l,r,mid,ans;scanf("%d",&n);for (i=1;i<=n;i++) {cin >> a[i][0];a[i][1]=a[i][0];lc[i]=rc[i]=0;len[i]=a[i][0].length();}scanf("%d",&m);for (i=n+1;i<=n+m;i++) {scanf("%d%d",&lc[i],&rc[i]);a[i][0]=a[lc[i]][0];if (len[lc[i]]<=100) {a[i][0]=a[i][0]+a[rc[i]][0];}if (a[i][0].length()>=100) a[i][0] = a[i][0].substr(0, 100);a[i][1]=a[rc[i]][1];if (len[rc[i]]<=100) {a[i][1]=a[lc[i]][1]+a[i][1];}if (a[i][1].length() >= 100) a[i][1] = a[i][1].substr(a[i][1].length() - 100, 100);l=0,r=100,ans=0;while (l<=r) {mid=(l+r)/2;if (check(mid,i)) ans=mid,l=mid+1; else r=mid-1;}printf("%d\n",ans);}//system("pause");return 0;}
阅读全文
0 0
- Codeforces 868D (Codeforces Round #438 D) Huge Strings 分治+哈希
- Codeforces Round #438 (Div. 1 + Div. 2 combined) D. Huge Strings
- Codeforces 868 D. Huge Strings (二分+随机+SAM)
- Codeforces 868 D. Huge Strings 字符串思维乱搞
- Codeforces 868 D Huge String
- Codeforces 168D Wizards and Huge Prize
- Codeforces Round #138 (Div. 2)D. Two Strings
- Codeforces Round #313 D. Equivalent Strings(DFS)
- Codeforces Round #313 (Div. 2) D. Equivalent Strings 字符串处理
- Codeforces Round #313 (Div. 2)D. Equivalent Strings(字符串)
- Codeforces Round #313 (Div. 2) D Equivalent Strings
- Codeforces Round #313 (Div. 2) Problem D - Equivalent Strings
- Equivalent Strings(Codeforces Round #313 (Div. 2) D)
- 规律+DFS Codeforces Round div2 D. Equivalent Strings
- Codeforces Round #313 (Div. 2) 560D Equivalent Strings(dos)
- Codeforces Round #358 (Div. 2) D. Alyona and Strings
- Codeforces Round #358 (Div. 2)D. Alyona and Strings
- Codeforces Round #358 (Div. 2) D. Alyona and Strings
- 【后台开发拾遗】异步代码同步化
- 显著性检测基础知识
- 预测的两类核心算法
- CodeForces
- java类加载器与反射学习笔记
- Codeforces 868D (Codeforces Round #438 D) Huge Strings 分治+哈希
- C语言、Java学习笔记(三)---几种简单的排序算法
- 大数据学习18:Hive在mysql的元数据表的关系和含义
- 可重入内核 & 可重入函数
- 102. Binary Tree Level Order Traversal
- CodeForces
- PAT备考
- java之流程控制与数组
- 以挂起的形式创建进程