标签:expec letters word ram ack str using ott too
题意:
给两个字符串只包含小写字母,长度分别为n,m
k个询问,每次询问给出一个L,R
任意的 ( i , j ) ( 1 ≤ i ≤ L , R ≤ j ≤ n ) 删除S串范围(i+1,j-1)内的字符,求出T串在新串内出现的次数总和
题解:
我还是照搬官方题解吧
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; typedef unsigned long long ULL; const long long INF = 1e18+1LL; const double pi = acos(-1.0); const int N = 6e4+10, M = 2e2+20,inf = 2e9; int zfail[N],ffail[N]; LL dp[N][M],f[N][M],sumdp[N][M],sumf[N][M],dp2[N][M],f2[N][M]; char a[N],b[N]; int n,m,k,T; LL solve(int ll,int rr) { LL ret = 0; ret += 1LL * sumdp[ll][m] * (n - rr + 1) + 1LL * sumf[rr][1] * (ll); for(int i = 1; i < m; ++i) { ret += 1LL*dp2[ll][i] * f2[rr][i+1]; } return ret; } void init() { for(int j = 0; j <= m+1; ++j) zfail[j] = 0,ffail[j] = m+1; for(int i = 0; i <= n+1; ++i) for(int j = 0; j <= m+1; ++j) dp[i][j] = 0,f[i][j] = 0,sumdp[i][j] = 0,sumf[i][j] = 0; int j = 0; for(int i = 2; i <= m; ++i) { while(j&&b[j+1]!=b[i]) j = zfail[j]; if(b[j+1] == b[i]) j++; zfail[i] = j; } j = m+1; for(int i = m-1; i >= 1; --i) { while(j<=m&&b[j-1]!=b[i]) j = ffail[j]; if(b[j-1] == b[i]) j--; ffail[i] = j; } j = 0; for(int i = 1; i <= n; ++i) { while(j&&a[i]!=b[j+1]) j = zfail[j]; if(b[j+1] == a[i]) j++; dp[i][j] += 1; } j = m+1; for(int i = n; i >= 1; --i) { while(j<=m&&b[j-1]!=a[i]) j = ffail[j]; if(b[j-1] == a[i]) j--; f[i][j] += 1; } for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { dp[i][j] += dp[i-1][j]; sumdp[i][j] += sumdp[i-1][j]+dp[i][j]; } } for(int i = n; i >= 1; --i) { for(int j = m; j >= 1; --j) { f[i][j] += f[i+1][j]; sumf[i][j] += sumf[i+1][j]+f[i][j]; } } } void init2() { for(int i = 0; i <= n+1; ++i) for(int j = 0; j <= m+1; ++j) dp2[i][j] = 0,f2[i][j] = 0; for(int i = 0; i <= n+1; ++i) dp2[i][0] = 1,f2[i][m+1] = 1; for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { if(a[i] == b[j] && dp2[i-1][j-1]) dp2[i][j] = 1; } } for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { dp2[i][j] += dp2[i-1][j]; } } for(int i = n; i >= 1; --i) { for(int j = m; j >= 1; --j) { if(a[i] == b[j] && f2[i+1][j+1]) f2[i][j] = 1; } } for(int i = n; i >= 1; --i) { for(int j = m; j >= 1; --j) { f2[i][j] += f2[i+1][j]; } } } int main() { scanf("%d",&T); while(T--) { scanf("%d%d%d%s%s",&n,&m,&k,a+1,b+1); init(); init2(); while(k--) { int L,R; scanf("%d%d",&L,&R); printf("%lld\n",solve(L,R)); } } return 0; }
HDU 6068 Classic Quotation KMP+DP
标签:expec letters word ram ack str using ott too
原文地址:http://www.cnblogs.com/zxhl/p/7293968.html