bzoj 5337 [TJOI2018] str
阿新 • • 發佈:2019-01-05
bzoj 5337 [TJOI2018] str
Link
Solution
水題
直接 \(f[i][j]\) 表示以第 \(i\) 位為結束位置,當前已經匹配了前 \(j\) 個氨基酸的方案數
使用雜湊轉移
轉移複雜度 \(O(10)\),總複雜度 \(1e7\)
Code
#include<stdio.h> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<map> #include<set> #include<cmath> #include<iostream> #include<queue> #include<string> #include<ctime> using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef long double ld; typedef unsigned long long ull; typedef pair<long long,long long> pll; #define fi first #define se second #define pb push_back #define mp make_pair #define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++) #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) #define Debug(...) fprintf(stderr, __VA_ARGS__) ll read(){ ll x=0,f=1;char c=getchar(); while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } const int md = 1e9 + 7; const ll mod = 2002070919ll; const int maxn = 10010; int n, len; char s[maxn], t[maxn]; int l[110][12], a[110], f[maxn][110]; ll hsh[110][12], pw[maxn], h[maxn]; inline void add(int &x, int y) { x += y; if (x >= md) x -= md; } inline ll calc(int l, int r) { return (h[r] - h[l - 1] * pw[r - l + 1] % mod + mod) % mod; } void work(){ n = read(); scanf("%s", s + 1); len = strlen(s + 1); pw[0] = 1; rep(i, 1, len) pw[i] = pw[i - 1] * 100 % mod; rep(i, 1, len) h[i] = (h[i - 1] * 100 + s[i] - 'A') % mod; rep(i, 1, n) { a[i] = read(); rep(j, 1, a[i]) { scanf("%s", t + 1); l[i][j] = strlen(t + 1); rep(k, 1, l[i][j]) hsh[i][j] = (hsh[i][j] * 100 + t[k] - 'A') % mod; } } rep(i, 0, len) f[i][0] = 1; rep(i, 1, len) rep(j, 1, n) { rep(k, 1, a[j]) { int nw = l[j][k]; if (i < nw || !f[i - nw][j - 1]) continue; ll val = calc(i - nw + 1, i); if (val == hsh[j][k]) add(f[i][j], f[i - nw][j - 1]); } } int ans = 0; rep(i, 1, len) add(ans, f[i][n]); printf("%d\n", ans); } int main(){ #ifdef LZT freopen("in","r",stdin); #endif work(); #ifdef LZT Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC); #endif }
Review
注意雜湊的模數不能大過 \(INT\_MAX\),不然兩個雜湊值相乘會爆 \(\text{long long}\)