535D Tavas and Malekas

Posted yzxverygood

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了535D Tavas and Malekas相关的知识,希望对你有一定的参考价值。

题目大意

给你一个串和m个下标

问你一个长度为n的串每一个下标开始的后缀的前缀都包含给定的串的方案数

分析

对于给定的串求出z数组

对于两个串不重叠的情况就是中间都不包含的数随便填即可

对于重叠的情况判断相交部分的左端点的z[i]是否大于等于重叠长度即可

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int mod = 1e9+7;
int n,m,q,z[1000100],ans,wh[1000100],pw[1000100];
char s[1000100];
inline void get_z()
    int i,j,k,l=0,r=0;
    z[0]=n;
    for(i=1;i<n;i++)
      if(i<=r)z[i]=min(r-i+1,z[i-l]);
      while(i+z[i]<n&&s[z[i]]==s[z[i]+i])z[i]++;
      if(i+z[i]-1>r)r=i+z[i]-1,l=i;
    

int main()
    int i,j,k;
    scanf("%d%d",&m,&q);
    scanf("%s",s);
    n=strlen(s);
    get_z();
    pw[0]=1;
    for(i=1;i<=1000000;i++)pw[i]=1ll*pw[i-1]*26%mod;
    for(i=1;i<=q;i++)scanf("%d",&wh[i]);
    if(!q)
      printf("%d\n",pw[m]);
      return 0;
    
    ans=pw[wh[1]-1];
    int la=wh[1]+n-1;
    for(i=2;i<=q;i++)
      if(wh[i]>la)ans=1ll*ans*pw[wh[i]-la-1]%mod;
        else 
          if(z[n-la+wh[i]-1]<la-wh[i]+1)
              puts("0");
              return 0;
          
        
      la=wh[i]+n-1;
      if(la>m)
          puts("0");
          return 0;
      
    
    if(m>la)ans=1ll*ans*pw[m-la]%mod;
    printf("%d\n",ans);
    return 0;

以上是关于535D Tavas and Malekas的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 535D - Tavas and Malekas

Codeforces Round #299 (Div. 2)D. Tavas and Malekas

Codeforces 536BTavas and Malekas

Codeforces B - Tavas and SaDDas

Tavas and Karafs 二分+结论

codeforces 536a//Tavas and Karafs// Codeforces Round #299(Div. 1)