题意:求字符串s的所有前缀出现次数之和。

http://www.cnblogs.com/jklongint/p/4446117.html

思路:用kmp做,简单且效率高。以前缀结尾的位置分类,令dp[i]为以结尾位置在i的前缀数量,那么dp[i] = cnt(j)(j~i是前缀),而由kmp的next函数的转移性质,可得如下递推方程:dp[i] = dp[next[i]] + 1,把这个递推式不断展开,也就是i = next[i]不断迭代,那么+1的个数就是dp[i] = cnt(j)(j~i是前缀)这个里面的cnt(j)了。这就是next数组的性质,实在巧妙!

 #pragma comment(linker, "/STACK:10240000,10240000")

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility> using namespace std; #define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define define_m int m = (l + r) >> 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl typedef double db;
typedef long long LL;
typedef pair<int, int> pii;
typedef multiset<int> msi;
typedef set<int> si;
typedef vector<int> vi;
typedef map<int, int> mii; const int dx[] = {, , -, , , , -, -};
const int dy[] = {-, , , , , -, , - };
const int maxn = 2e5 + ;
const int md = ;
const int inf = 1e9 + ;
const LL inf_L = 1e18 + ;
const double pi = acos(-1.0);
const double eps = 1e-; template<class T>T gcd(T a, T b){return b==?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; } struct KMP {
int next[];
void GetNext(char s[]) {
mem0(next);
next[] = next[] = ;
for(int i = ; s[i]; i++) {
int j = next[i];
while(j && s[i] != s[j]) j = next[j];
next[i + ] = s[j] == s[i]? j + : ;
}
}
}; KMP kmp;
int dp[maxn];
char s[maxn]; int main() {
//freopen("in.txt", "r", stdin);
int T, n;
cin >> T;
while (T--) {
scanf("%d%s", &n, s);
kmp.GetNext(s);
mem0(dp);
int ans = n;
rep_up1(i, n) {
if (kmp.next[i] == ) continue;
dp[i] = dp[kmp.next[i]] + ;
dp[i] %= md;
ans += dp[i];
ans %= md;
}
cout << ans << endl;
}
return ;
}

[hdu3336]kmp(后缀数组)的更多相关文章

  1. POJ2406 Power Strings(KMP,后缀数组)

    这题可以用后缀数组,KMP方法做 后缀数组做法开始想不出来,看的题解,方法是枚举串长len的约数k,看lcp(suffix(0), suffix(k))的长度是否为n- k ,若为真则len / k即 ...

  2. POJ 2406 KMP/后缀数组

    题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就 ...

  3. POJ-3450 Corporate Identity (KMP+后缀数组)

    Description Beside other services, ACM helps companies to clearly state their “corporate identity”, ...

  4. 【HDU - 5442】Favorite Donut 【最大表示法+KMP/后缀数组】

    题意 给出一个长度为n的环状由小写字母组成的序列,请找出从何处断开,顺时针还是逆时针,使得字典序最大.如果两个字符串的字典序一样大,那么它会选择下下标最小的那个.如果某个点顺时针逆时针产生的字典序大小 ...

  5. POJ2406Power Strings (最小循环节)(KMP||后缀数组)

    Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc&quo ...

  6. luogu 2463 [SDOI2008]Sandy的卡片 kmp || 后缀数组 n个串的最长公共子串

    题目链接 Description 给出\(n\)个序列.找出这\(n\)个序列的最长相同子串. 在这里,相同定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串. 思路 参考:hzwe ...

  7. ZOJ1905Power Strings (KMP||后缀数组+RMQ求循环节)

    Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc&quo ...

  8. POJ3080方法很多(暴力,KMP,后缀数组,DP)

    题意:       给n个串(n>=2&&n<=10),每个串长度都是60,然后问所有串的最长公共子串,如果答案不唯一输出字典序最小的. 思路:直接暴力,枚举+KMP,后缀 ...

  9. LightOJ 1428 Melody Comparison (KMP + 后缀数组)

    题意:给定两个串A,B,问你A有多少不同的子串,并且不包含B. 析:首先A有多少个不同的子串,可以用后缀数组来解决,也就是 n - sa[i] - h[i] + 1.但是要是不包含B,可以先预处理A和 ...

随机推荐

  1. Mysql:小主键,大问题

    今日格言:让一切回归原点,回归最初的为什么. 本篇讲解 Mysql 的主键问题,从为什么的角度来了解 Mysql 主键相关的知识,并拓展到主键的生成方案问题.再也不怕被问到 Mysql 时只知道 CR ...

  2. Python实现按键精灵(一)-键鼠操作

    需要安装 pywin32库 pip install pywin32 import win32api import time #鼠标移动 def mouse_move(x,y): win32api.Se ...

  3. weblogic漏洞(一)----CVE-2017-10271

    WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271) 0x01 漏洞原因: Weblogic的WLS Security组件对外提供webservice服务,其中使用了XM ...

  4. vue+element-ui中引入阿里播放器

    1.在public文件下的index.html文件中插入以下代码: <link rel="stylesheet" href="https://g.alicdn.co ...

  5. SQL Server 之T-SQL基本语句 (2)

    接下来继续用上述例子来总结知识点. 用通配符进行过滤 LIKE操作符 //用来选择与条件一样或部分相似的数据 select name from person where name like 'chen ...

  6. Pycharm 操作数据库

    view--->Tool Buttons,点击Pycharm右侧的Database 1.连接数据库       2.建立一个表,添加数据   通过以上操作把用户名和密码储存到了数据库中  3.连 ...

  7. 手机照片的exif里有方向属性

    <?php $image = imagecreatefromstring(file_get_contents($_FILES['image_upload']['tmp_name'])); $ex ...

  8. 2019-2020-1 20199328《Linux内核原理与分析》第二周作业

    冯诺依曼体系结构的核心是: 冯诺依曼体系结构五大部分:控制器,运算器,存储器,输入输出设备. 常用的寄存器 AX.BX.CX.DX一般存放一些一般的数据,被称为通用寄存器,分别拥有高8位和低8位. 段 ...

  9. 二、Vue基础语法

    六:Vue的v-bind指令作用:绑定标签上的所有属性其简写 ":" 6.1:    例如:<p v-bind:id="test">Hello wo ...

  10. 第三方库 正则表达式re模块

    正则表通常被用来检索.替换那些符合某个模式(规则)的文本. 正则表达式通常缩写成“regex”,单数有regexp.regex,复数有regexps.regexes.regexen. 正则表达式是对字 ...