Games on a CD CodeForces - 727E(双hash)

    xiaoxiao2022-07-06  190

    题意

    给你一个长度为n*k的环,环上每一个位置有一个字符。 现在给你g个长度为k的字符串,问是否可以在g个字符串中找出k个构成这个环。

    思路

    有0到k枚举,然后双hash就可以。

    #include <iostream> #include <map> #include <cstring> #include <vector> using namespace std; const int MAXN=3e6+10; char str1[MAXN],str2[MAXN]; const int seed=13331; const int mod1=1000000007; const int mod2 = 19260817; typedef long long ll; typedef pair<ll,ll> pll; ll xp[2][MAXN],hash_1[2][MAXN],hash_2[2][MAXN]; pll temp[MAXN]; int ans[MAXN]; void init() { xp[0][0]=1; for(int i=1;i<MAXN;i++) xp[0][i]=(xp[0][i-1]*13331)%mod1; xp[1][0]=1; for(int i=1;i<MAXN;i++) xp[1][i]=(xp[1][i-1]*1331)%mod2; } pll get_hash(int i,int l,ll hash[][MAXN]) { ll a=((hash[0][i]-hash[0][i+l]*xp[0][l])%mod1+mod1)%mod1; ll b=((hash[1][i]-hash[1][i+l]*xp[1][l])%mod2+mod2)%mod2; return pll(a,b); } pll make_hash(char str[],ll hash[][MAXN]) { int len=strlen(str); hash[0][len]=0; hash[1][len]=0; for(int i=len-1;i>=0;i--) { hash[0][i]=(hash[0][i+1]*13331%mod1+str[i]-'a'+1)%mod1; hash[1][i]=(hash[1][i+1]*1331%mod2+str[i]-'a'+1)%mod2; } return get_hash(0,len,hash); } map<pll,int> mp; map<pll,vector<int>> mp2; int main() { int n,k; init(); scanf("%d%d",&n,&k); scanf("%s",str1); int len=n*k; for(int i=len;i<len+len;i++) str1[i]=str1[i-len]; make_hash(str1,hash_1); int g; scanf("%d",&g); for(int i=0;i<g;i++) { scanf("%s",str2); pll t1=make_hash(str2,hash_2); mp2[t1].push_back(i+1); mp[t1]++; } for(int i=0;i<k;i++) { int fg=1; int cont=0; int cont1=0; for(int j=i;j<=i+len-k;j+=k) { pll t2=get_hash(j,k,hash_1); if(!mp[t2]) { fg=0; break; } else { temp[cont++]=t2; mp[t2]--; ans[cont1++]=mp2[t2].back(); mp2[t2].pop_back(); } } if(fg) { printf("YES\n"); for(int j=0;j<cont1;j++) if(!j) printf("%d",ans[j]); else printf(" %d",ans[j]); return 0; } else { for(int j=0;j<cont;j++) { mp[temp[j]]++; mp2[temp[j]].push_back(ans[j]); } } } printf("NO\n"); return 0; }

     

    最新回复(0)