您的位置:首页 > 其它

codeforces 727E. Games on a CD(双Hash

2017-07-21 15:40 267 查看
题目链接:http://codeforces.com/contest/727/problem/E 
题目大意:有g个长度为k的互不相同的字符串,从中选择n个按照顺时针顺序写下形成一个环s。给出s(长度为n*k)和g个字符串,求是否有一种选择方案可以得到s(可以从任意位置开始)。 
数据范围:1 ≤ n ≤ 10^5, 1 ≤ k ≤ 10^5, n*k ≤ 10^6, n ≤ g ≤ 10^5, g*k ≤ 2*10^6

题解更详细版

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const int maxn =2e6 + 20;
const ll mod0 = 1e9 + 7,mod1 = 19260817;
map<P,int> dp;
set<int > S;
ll hash0[maxn],hash1[maxn],vis[maxn],seed = 31,A0[maxn],A1[maxn],G[maxn][2];
char str[maxn],str0[maxn];
int main(void)
{
int n,k;
cin>>n>>k;
A0[0] = A1[0] = 1;
for(int i = 1; i <= k; i ++) A0[i] = A0[i - 1] * seed % mod0,
A1[i] = A1[i - 1] * seed % mod1;
scanf("%s",str0);
int len = n * k;
for(int i = 0; i < len; i ++)
str0[i + len] = str0[i];
int g;
cin>>g;
for(int i =0 ; i < g; i ++)
{
scanf("%s",str);
P p;
for(int j = 0; j < k; j ++)
{
p.first = (p.first * seed + str[j] - 'a') % mod0;
p.second = (p.second * seed + str[j] - 'a') % mod1;
}
dp[p] = i + 1;
}
for(int i =1 ;str0[i - 1]; i ++)
{
hash0[i] = (hash0[i - 1] * seed + str0[i - 1] - 'a') % mod0;
hash1[i] = (hash1[i - 1] * seed + str0[i - 1] - 'a') % mod1;
}
for(int i =0 ; i < k; i ++)
{
for(int z = 1; z <= n; z ++) vis[z] = 0;
S.clear();
for(int j = 1; j <= n; j ++)
{
P p = P((hash0[j * k + i] - (hash0[(j - 1) * k + i] * A0[k] % mod0) + mod0) % mod0,
(hash1[j * k + i] - (hash1[(j - 1) * k + i] * A1[k] % mod1 ) + mod1) % mod1);
vis[j] = dp[p];
if(S.find(vis[j]) != S.end()) break;
S.insert(vis[j]);
}
int Min = *min_element(vis + 1,vis + 1 + n);
if(S.size() == n && Min)
{
cout<<"YES"<<endl;
for(int j = 1; j <= n; j ++)
cout<< vis[j]<<" ";
return 0;
}
}
cout<<"NO"<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: