hdoj 6153 A Secret
来源:互联网 发布:head first java电子书 编辑:程序博客网 时间:2024/06/05 03:53
题目链接:A Secret
题目大意:给你两个字符串,然后需要你对模式串的后缀去对原串匹配,原串后缀长度为1的出现多少次贡献就是1*n,长度为2的贡献就是2*n,然后要求你算出这个总贡献mod(1e9+7)
题目思路:既然要求的是后缀匹配,那么我们将两个串都翻转过来进行正着匹配就好了,然后我们需要去在KMP里面去算,当KMP匹配到失配的时候那么我们可以知道这时的j就是我们已经匹配成功的串,那么这个串的贡献是多少呢?自然是j*(j+1)/2,因为匹配了j个字符,那么j-1、j-2、…、1个字符肯定都在这之前已经匹配到了,还需要注意的一个问题是,最后失配的情况,可能一直到最后都不会失配,所以我们让其失配,然后就做一下处理就好了,这题因为j*(j+1)/2是整数,所以不需要用逆元去算,直接暴力去算就好了
#include <map>#include <set>#include <queue>#include <stack>#include <cmath>#include <vector>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 1e6+10;const int mod = 1e9+7;ll n,Next[maxn],ret;char mo[maxn],str[maxn],ans[maxn];void getNext(){ ll i = 0,j = -1,len = strlen(mo); while(i < len){ if(j == -1||mo[i] == mo[j]) Next[++i] = ++j; else j = Next[j]; }}void kmp(){ ll i = 0,j = 0,len1 = strlen(mo),len2 = strlen(str); ll ans = 0; while(i < len2){ if(j == -1||mo[j] == str[i]){ j++; i++; } else ret = (ret+((j+1)*j)/2)%mod,j = Next[j]; } while(j != -1){ ret = (ret+((j+1)*j)/2)%mod; j = Next[j]; } printf("%lld\n",ret);}int main(){ int t; scanf("%d",&t); while(t--){ ret = 0ll; scanf("%s%s",str,mo); reverse(str,str+strlen(str)); reverse(mo,mo+strlen(mo)); memset(Next,-1,sizeof(Next)); getNext(); kmp(); } return 0;}
Uupdate:这个KMP写法有问题,有一组数据str:baabaa
mo:caabaa过不去,所以需要使用正确的姿势:
#include <bits/stdc++.h>using namespace std;const int N = 1000005;const int Q = 1e9 + 7;char s[N] , t[N];int n , m , f[N] , cnt[N];void work() { scanf("%s%s" , t , s); n = strlen(t); m = strlen(s); reverse(s , s + m); reverse(t , t + n); f[0] = f[1] = 0; for (int i = 1 ; i < m ; ++ i) { int j = f[i]; while (j && s[i] != s[j]) j = f[j]; f[i + 1] = s[i] == s[j] ? j + 1 : 0; } memset(cnt , 0 , sizeof(int) * (m + 1)); for (int i = 0 , j = 0 ; i < n ; ++ i) { while (j && t[i] != s[j]) j = f[j]; j += (t[i] == s[j]); ++ cnt[j]; } for (int i = m ; i > 0 ; -- i) { cnt[f[i]] += cnt[i]; } int res = 0; for (int i = 1 ; i <= m ; ++ i) { res += (long long)cnt[i] * i % Q; res %= Q; } cout << res << endl;}int main() { int T; scanf("%d" , &T); while (T --) { work(); }}
阅读全文
0 0
- hdoj 6153 A Secret
- HDU 6153 A Secret
- hdu-6153 A Secret
- hdu-6153 A Secret
- HDU 6153 A Secret
- hdu--6153(A Secret)
- hdu 6153 A Secret KMP
- HDU 6153 A Secret KMP
- HDU 6153 A Secret KMP
- Hdu 6153 A Secret【KMP】
- 【KMP】HDU 6153 A Secret
- HDU 6153 A Secret(KMP)
- hdu 6153 A Secret (kmp)
- hdu 6153 A Secret (KMP)
- hdu 6153 A Secret(KMP)
- hdu 6153 A Secret(KMP)
- HDU 6153 A secret(kmp)
- A Secret
- ZOJ2401 Zipper 双塔式 DP
- 程序片段----获得目录下的文件名
- apt——搜索包
- 微信页面跳转的几种方法
- I/O流学习--InputStream的读取文件方法
- hdoj 6153 A Secret
- 语音信号的预处理
- selenium的安装
- Unity入门操作_线性,球形检测_014
- 如果程序员能早知道这些该有多好!
- MyBatis笔记(一)
- jmeter函数和变量(二)
- js视频学习笔记2
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path