• bzoj 5337 [TJOI2018] str


    bzoj 5337 [TJOI2018] str

    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
    ", ans);
    }
    
    int main(){
    	#ifdef LZT
    		freopen("in","r",stdin);
    	#endif
    	
    	work();
    	
    	#ifdef LZT
    		Debug("My Time: %.3lfms
    ", (double)clock() / CLOCKS_PER_SEC);
    	#endif
    }
    

    Review

    注意哈希的模数不能大过 (INT\_MAX),不然两个哈希值相乘会爆 ( ext{long long})

  • 相关阅读:
    K均值算法
    4.K均值算法应用
    js实现点击不同按钮切换内容
    vue框架中的日期组件转换为yyymmdd格式
    sessionStorage和localStorage的使用方法
    vue中使用axios
    js中的原型对象链
    web端常见测试点
    软件测试手工测试
    前端面试题vue部分
  • 原文地址:https://www.cnblogs.com/wawawa8/p/10225906.html
Copyright © 2020-2023  润新知