• 20201029模拟赛总结


    T1

    看到这题第一眼感觉这不是直接暴力就可以吗……

    尽管如此,我还是莫名其妙的写了一个 (KMP) 尽管什么也没有用到,然后它跑 (RE) 了导致 (60pts) 溜了。

    其实我们只需要循环比较,比较长度是较长字符串的二倍即可啦!

    T2

    这题的根号居然是实数意义下的,我以为是整数意义下直接懵逼爆零滚粗 qwq 。

    我们化简 (sqrt {m} = ksqrt b) , 发现若要等式成立那么 (sqrt x) 必须是 (sqrt b) 的倍数。

    那么也就是说我们要求出数列 (a_1 , a_2 , a_3 , dots , a_{n-1} , a_n) 使得 (sumlimits_{i=1}^n a_i = k) 即可,数量可用插板法求解。

    T3

    这道题一眼就发现不可做,然而我却成功的在样例特水无大样例的情况下通过了这道题!!!

    我们考虑 (DP) ,设状态 (dp[i][j][k]) 为 前 (i) 个字母现在匹配到第 (j) 个句式的第 (k) 个单词的方案数,然后在单词结尾处转移即可,可以使用 AC自动机 处理。

    code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define ll long long
    using namespace std;
    
    int read()
    {
    	int a = 0,x = 1;char ch = getchar();
    	while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
    	while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
    	return a*x;
    }
    const int N=1007,P=1000000007;
    int n,m;
    char s[N];
    int ch[N][27],vis[N],p[N],len[N],nxt[N],cnt;
    bool ins[N][11];
    void add(int num)
    {
    	int t = 1;len[num] = strlen(s+1);
    	for(int i = 1;i <= len[num];i ++){
    		if(!ch[t][s[i]-'a']) ch[t][s[i]-'a'] = ++cnt;
    		t = ch[t][s[i]-'a'];
    	}
    	if(!vis[t]) vis[t] = num;
    	int tmp = read();
    	for(int i = 1;i <= tmp;i ++) {
    		int a = read();
    		if(!ins[vis[t]][a]) {p[num] ++,ins[vis[t]][a] = 1;}
    	}
    }
    queue<int>q;
    void init()
    {
    	for(int i = 0;i < 26;i ++) ch[0][i] = 1;
    	q.push(1);
    	while(!q.empty()) {
    		int u = q.front();q.pop();
    		printf("%d
    ",u);
    		for(int i = 0;i < 26;i ++) {
    			if(!ch[u][i]) ch[u][i] = ch[nxt[u]][i];
    			else {
    				nxt[ch[u][i]] = ch[nxt[u]][i];
    				q.push(ch[u][i]);
    			}
    		}
    	//	getchar();
    	}
    }
    
    int num[12],wo[12][12];
    ll dp[N][12][12],f[N];
    
    #define fa nxt
    int find(int s,int i)
    {
    	if(!s) return s;
    	if(!vis[s]) return fa[s] = find(fa[s],i);
    	find(fa[s],i);
    	for(int j = 1;j <= m;j ++) {
    		for(int k = 1;k <= num[j];k ++) {
    			if(ins[vis[s]][wo[j][k]]) {
    				if(k > 1) {
    					(dp[i][j][k] += dp[i-len[vis[s]]][j][k-1]) %= P;
    				} else (dp[i][j][k] += f[i-len[vis[s]]]) %= P;
    			}	
    		}
    	}
    	return s;
    }
    #undef fa
    
    int main()
    {
    	freopen("word.in","r",stdin);
    	freopen("word.out","w",stdout);
    	n = read(),m = read(),cnt = 1;
    	for(int i = 1;i <= n;i ++) {
    		scanf("%s",s+1);
    		add(i);
    	}
    	init();
    	for(int i = 1;i <= m;i ++) {
    		num[i] = read();
    		for(int j = 1;j <= num[i];j ++) wo[i][j] = read();
    	}
    	scanf("%s",s+1);int l = strlen(s+1);
    	f[0] = 1;for(int i = 1,t = 1;i <= l;i ++) {
    		t = ch[t][s[i]-'a'];find(t,i);
    		for(int j = 1;j <= m;j ++) (f[i] += dp[i][j][num[j]]) %= P;
    	}
    	printf("%lld",f[l]);
    	return 0;
    }
    
  • 相关阅读:
    ios UIImageView
    ios UILable
    [leetCode]116. 填充每个节点的下一个右侧节点指针
    [leetCode]1002. 查找常用字符
    [leetCode]199. 二叉树的右视图
    [leetCode]784. 字母大小写全排列
    [leetCode]1297. 子串的最大出现次数
    [leetCode]1239. 串联字符串的最大长度
    1095. 山脉数组中查找目标值
    [leetCode]1235. 规划兼职工作
  • 原文地址:https://www.cnblogs.com/nao-nao/p/13898683.html
Copyright © 2020-2023  润新知