题意:给一个串s,求s的每个前缀出现次数之和。

思路:对于一个后缀i,设i和原串的最长公共前缀为k,则当前总共可以产生k个答案。因此原题转化为求所有后缀与原串的最长公共前缀之和。模板题。以下为通过模板。

 #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 = 1e5 + ;
const int md = 1e9 + ;
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 SparseTable {
int d[maxn][];
int t[maxn];
int n;
void resize(int nn) { n = nn; }
void Init_min(int a[]) {
rep_up0(i, n) d[i][] = a[i];
for (int j = ; ( << j) <= n; j++) {
for (int i = ; i + ( << j) - < n; i++) {
d[i][j] = min(d[i][j - ], d[i + ( << (j - ))][j - ]);
}
}
int p = -;
rep_up1(i, n) {
if ((i & (i - )) == ) p++;
t[i] = p;
}
}
void Init_max(int a[]) {
rep_up0(i, n) d[i][] = a[i];
for (int j = ; ( << j) <= n; j++) {
for (int i = ; i + ( << j) - < n; i++) {
d[i][j] = max(d[i][j - ], d[i + ( << (j - ))][j - ]);
}
}
int p = -;
rep_up1(i, n) {
if ((i & (i - ) == )) p++;
t[i] = p;
}
}
int RMQ_min(int L, int R) {
int p = t[R - L + ];
return min(d[L][p], d[R - ( << p) + ][p]);
}
int RMQ_max(int L, int R) {
int p = t[R - L + ];
return max(d[L][p], d[R - ( << p) + ][p]);
}
}; /// 构造后缀数组的之前,需要在原串末尾加个空字符(比其它字符都小即可),
///把这个空字符看成原串的一部分(这样在比较的时候到这个位置一定可以分个大小),
///所以n应该为原序列长度+1,后缀n-1是"空串",sa[0]总是n-1。
struct SuffixArray {
int n;
int arr[][maxn];
int *sa = arr[], *x = arr[], *y = arr[], *c = arr[], *rnk = arr[], *height = arr[];
void resize(int nn) { n = nn; mem0(arr[]); }
void build_sa(int s[], int m) { // m is biger than the max value of char
rep_up0(i, m) c[i] = ;
rep_up0(i, n) c[x[i] = s[i]]++;
rep_up1(i, m - ) c[i] += c[i - ];
rep_down0(i, n) sa[--c[x[i]]] = i;
for (int k = ; k <= n; k <<= ) {
int p = ;
for (int i = n - k; i < n; i++) y[p++] = i;
rep_up0(i, n) if (sa[i] >= k) y[p++] = sa[i] - k;
rep_up0(i, m) c[i] = ;
rep_up0(i, n) c[x[y[i]]]++;
rep_up0(i, m) c[i] += c[i - ];
rep_down0(i, n) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = ; x[sa[]] = ;
for (int i = ; i < n; i++) {
x[sa[i]] = y[sa[i - ]] == y[sa[i]] && y[sa[i - ] + k] == y[sa[i] + k]? p - : p++;
}
if (p >= n) break;
m = p;
}
}
void build_height(int s[]) {
int k = ;
rep_up0(i, n) rnk[sa[i]] = i;
rep_up0(i, n) {
if (k) k--;
int j = sa[rnk[i] - ];
while (s[i + k] == s[j + k]) k++;
height[rnk[i]] = k;
}
}
}; SparseTable st;
SuffixArray sa;
char s[maxn];
int ss[maxn]; int main() {
//freopen("in.txt", "r", stdin);
while (~scanf("%s", s)) {
int len = strlen(s) + ;
rep_up0(i, len) ss[i] = s[i];
sa.resize(len);
sa.build_sa(ss, );
sa.build_height(ss);
st.resize(len);
st.Init_min(sa.height);
int ans = (len - ) % ;
for (int i = ; i < len; i++) {
int j = sa.rnk[], k = sa.rnk[i];
if (j > k) swap(j, k);
ans += st.RMQ_min(j + , k);
ans %= ;
}
cout << ans << endl;
}
return ;
}

[hdu4552]最长公共前缀的更多相关文章

  1. [转][LeetCode]Longest Common Prefix ——求字符串的最长公共前缀

    题记: 这道题不难但是很有意思,有两种解题思路,可以说一种是横向扫描,一种是纵向扫描. 横向扫描:遍历所有字符串,每次跟当前得出的最长公共前缀串进行对比,不断修正,最后得出最长公共前缀串. 纵向扫描: ...

  2. lintcode :最长公共前缀

    题目 最长公共前缀 给k个字符串,求出他们的最长公共前缀(LCP) 样例 在 "ABCD" "ABEF" 和 "ACEF" 中,  LCP ...

  3. LeetCode Longest Common Prefix 最长公共前缀

    题意:给多个字符串,返回这些字符串的最长公共前缀. 思路:直接逐个统计同一个位置上的字符有多少种,如果只有1种,那么就是该位是相同的,进入下一位比较.否则终止比较,返回前缀.可能有一个字符串会比较短, ...

  4. 扩展KMP--求字符串S的所有后缀和字符串T的最长公共前缀

    在解上面这个问题前我们要先解决一个类似的问题:求字符串s的所有后缀和s本身的最长公共前缀: 我们用next[]数组保存这些值: 现在我们假设要求next[ x ],并且next[ i ] 0<i ...

  5. BNUOJ34990--Justice String (exkmp求最长公共前缀)

    Justice String Given two strings A and B, your task is to find a substring of A called justice strin ...

  6. [Swift]LeetCode14. 最长公共前缀 | Longest Common Prefix

    Write a function to find the longest common prefix string amongst an array of strings. If there is n ...

  7. [LeeCode]14. 最长公共前缀

    题目链接:https://leetcode-cn.com/problems/longest-common-prefix/ 题目描述: 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀 ...

  8. python(leetcode)-14最长公共前缀

    编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...

  9. leetcode-14最长公共前缀

    leetcode-14最长公共前缀 题目 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower& ...

随机推荐

  1. billu b0x2靶机渗透

    实战渗透靶机billu b0x2 攻击kali :192.168.41.147 靶机b0x2: 192.168.41.148 起手先nmap扫了一下 扫到了四个开放的端口,有ssh,http,rpcb ...

  2. OAuth-授权机制

    一.应用场景 有一个"云冲印"的网站,可以将用户储存在Google的照片,冲印出来.用户为了使用该服务,必须让"云冲印"读取自己储存在Google上的照片. 问 ...

  3. orcale 多列转一行显示

    强大的数据库有个自带函数wm_concat() wm_concat()这个函数放的是需要汇总的列 select wm_concat(name) name  from tablename

  4. UnicodeDecodeError: 'gbk' codec can't decode byte 0x8a in position 2: illegal multibyte sequence

    pycharm报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x8a in position 2: illegal multibyte seq ...

  5. C#客户端打印条形码

    第一种方法: 引用第三方插件文件zxing.dll // 1.设置条形码规格 EncodingOptions encodeOption = new EncodingOptions(); encodeO ...

  6. jeecg ant design vue 一些收藏

    1关于 进来清除上次记录 找到src/permission.js下的

  7. PHP中的数据库操作

    PDO project data object 连接到数据库 $db=new PDO("mysql:dbname=database;host=sever","userna ...

  8. web--ajax--json

    案例: 其中,用eval()解析的话,如果json有一些代码,如:{"age":"alert(你好)"},他也会帮你实行,而JOSN.parse();则会自动报 ...

  9. Spring框架中文件目录遍历漏洞 Directory traversal in Spring framework

    官方给出的描述是Spring框架中报告了一个与静态资源处理相关的目录遍历漏洞.某些URL在使用前未正确加密,使得攻击者能够获取文件系统上的任何文件,这些文件也可用于运行SpringWeb应用程序的进程 ...

  10. Handler 机制(一)—— Handler的实现流程

    由于Android采用的是单线程模式,开发者无法在子线程中更新 UI,所以系统给我提供了 Handler 这个类来实现 UI 更新问题.本贴主要说明 Handler 的工作流程. 1. Handler ...