1. 程式人生 > >Codeforces 535D - Tavas and Malekas

Codeforces 535D - Tavas and Malekas

span 查找 () -- while end eof eight amp

535D - Tavas and Malekas

思路:先把字符串填充好(後面填充的把前面覆蓋掉),然後用KMP查找有多少個子串,如果比填充的少,說明有些覆蓋矛盾,輸出0;否則,設不確定的點的個數為k,答案為(26^k)%(1e9+7)。

代碼:

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define pb push_back
#define mem(a,b) memset((a),(b),sizeof(a))
const int N=1e6+5;
const int MOD=1e9+7
; int f[N]={-1}; bool vis[N]={false}; bool vis1[N]={false}; int main() { ios::sync_with_stdio(false); cin.tie(0); int n,t,a; string s; cin>>n>>t; cin>>s; int tt=t; while(t--) { cin>>a; vis[a-1]=true;//假裝填上了,其實也就是標記一下第一個點 }
int m=s.size(); for(int i=1;i<m;i++) { int j=f[i-1]; while(s[j+1]!=s[i]&&j>=0)j=f[j]; if(s[j+1]==s[i])f[i]=j+1; else f[i]=-1; } int i=0,j=0,cnt=0; t=-1; while(i<n) { if(vis[i])t=i;//把標記那個點更新一下 if(t!=-1) {
if(i-t<m) { vis1[i]=true;//把填過的點標記下 if(s[i-t]==s[j])//本質是s串自己和自己比較啊 { i++; j++; if(j==m) { cnt++; j=f[j-1]+1; } } else { if(j==0)i++; else j=f[j-1]+1; } } else i++; } else i++; } if(cnt<tt) { cout<<0<<endl; return 0; } ll ans=1; for(int i=0;i<n;i++)if(!vis1[i])ans=(ans*26)%MOD; cout<<ans<<endl; return 0; }

Codeforces 535D - Tavas and Malekas