题意:给定一个长为n的字符串,求其每个位置开始于其自身暴力匹配出相同或不同的结果的总比较次数
n<=1e6
思路:exkmp板子
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 //typedef pair<ll,ll>P; 11 #define N 1000010 12 #define M 200010 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pb push_back 17 #define pi acos(-1) 18 #define mem(a,b) memset(a,b,sizeof(a)) 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 21 #define lowbit(x) x&(-x) 22 #define Rand (rand()*(1<<16)+rand()) 23 #define id(x) ((x)<=B?(x):m-n/(x)+1) 24 #define ls p<<1 25 #define rs p<<1|1 26 27 const int MOD=1e9+7,inv2=(MOD+1)/2; 28 double eps=1e-4; 29 int INF=1e9; 30 int inf=0x7fffffff; 31 int dx[4]={-1,1,0,0}; 32 int dy[4]={0,0,-1,1}; 33 34 int nxt[N],ext[N]; 35 char s[N],t[N]; 36 37 int read() 38 { 39 int v=0,f=1; 40 char c=getchar(); 41 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 42 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 43 return v*f; 44 } 45 46 47 int main() 48 { 49 int cas=read(); 50 while(cas--) 51 { 52 int n,m; 53 //scanf("%s",s+1); 54 scanf("%s",t+1); 55 //n=strlen(s+1); 56 m=strlen(t+1); 57 nxt[1]=m; 58 int id=0,p=0; 59 rep(i,2,m) 60 { 61 int j=nxt[i-id+1]; 62 if(i+j>p) 63 for(j=max(p-i,0);i+j<=m&&t[j+1]==t[i+j];j++); 64 nxt[i]=j; 65 if(i+j-1>p) 66 id=i,p=i+j-1; 67 } 68 ll ans=0; 69 rep(i,2,m) 70 if(nxt[i]+i>m) ans+=nxt[i]; 71 else ans+=(nxt[i]+1); 72 /*id=p=0; 73 for(int i=1;i<=n;i++) 74 { 75 int j=nxt[i-id+1]; 76 if(i+j>p) 77 for(j=max(p-i,0);i+j<=n&&t[j+1]==s[i+j];j++); 78 ext[i]=j; 79 if(i+j-1>p) id=i,p=i+j-1; 80 } 81 for(int i=1;i<=m;i++) printf("%d ",nxt[i]); 82 printf(" "); 83 for(int i=1;i<=n;i++) printf("%d ",ext[i]); 84 printf(" ");*/ 85 printf("%I64d ",ans); 86 } 87 return 0; 88 }