• 19.32%
  • 1000ms
  • 256000K

A number is skr, if and only if it's unchanged after being reversed. For example, "12321", "11" and "1" are skr numbers, but "123", "221" are not. FYW has a string of numbers, each substring can present a number, he wants to know the sum of distinct skr number in the string. FYW are not good at math, so he asks you for help.

Input

The only line contains the string of numbers SS.

It is guaranteed that 1 \le S[i] \le 91≤S[i]≤9, the length of SS is less than 20000002000000.

Output

Print the answer modulo 10000000071000000007.

样例输入1复制

111111

样例输出1复制

123456

样例输入2复制

1121

样例输出2复制

135

题目来源

ACM-ICPC 2018 南京赛区网络预赛

就是一道回文自动机的模板

回文自动机用来求一个字符串中的种类或个数

因为这道题还去了解了一下Trie树和AC自动机 虽然好像还不是很会用 有空去找道题做一下好了

回文自动机的结构(我还是喜欢叫他自动机, 虽然我都不太理解自动机):

存在两个树结构,分别记录奇数|偶数长度的回文;

每个点记录一种字符串(但是由于可以通过根到该节点的路径确定这个字符串是什么,于是并不需要真的在该节点记录/*写下*/这个信息)【Trie树】

每个节点连字符x边向一个子节点,表示在她的左右两边加x构成的回文是这个总字符串的子串(根节点相关部分单独定义);

每个节点连一条fail指针向其最长后缀回文;

一开始回文树有两个节点,0表示偶数长度串的根和1表示奇数长度串的根,且len[0] = 0,len[1] = -1,last = 0,S[0] = -1

偶数的fail指向奇数的

详细过程见:https://blog.csdn.net/u013368721/article/details/42100363


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<vector>
#include<set>
//#include<bits/stdc++.h>
#define inf 0x7f7f7f7f7f7f7f7f
using namespace std;
typedef long long LL; const int maxn = 2e6 + 10;
const LL mod = 1000000007; LL read()
{
LL x = 0, f = 1;
register char ch = getchar();
while(ch < '0' || ch > '9'){
if(ch == '-'){
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
} LL pow_mod(LL a, LL b, LL p)
{
LL ret = 1;
while(b){
if(b & 1){
ret = (ret * a) % p;
}
a = (a * a) % p;
b >>= 1;
}
return ret;
} LL fermat(LL a, LL p)//求a关于b的逆元
{
return pow_mod(a, p - 2, p);
} LL ans, llen;
LL _10[maxn], inv10[maxn];
LL sum[maxn], rsum[maxn];//sum[i]是子串0-i表示的数值, rsum[i]是子串i到len表示的数值
char str[maxn]; struct PT{
char s[maxn];//s[i]表示第i个添加的字符
int last, cur, tot;//last指向新添加一个字母后所形成的最长回文串表示的节点, tot表示节点个数
int son[maxn][10];
int fail[maxn], len[maxn];//len[i]表示编号为i的节点表示的回文串的长度
void init(){
s[0] = -1;
last = cur = 0;
tot = 1;
for(int i = 0; i <= 9; i++){
son[0][i] = son[1][i] = 0;
}
len[0] = 0;
len[1] = -1;
fail[0] = 1;
fail[1] = 0;
} int node(int l){
++tot;
for(int i = 0; i <= 9; i++){
son[tot][i] = 0;
}
fail[tot] = 0;
len[tot] = l;
return tot;
} int getfail(int x){
while(s[cur - len[x] - 1] ^ s[cur]){
x = fail[x];
}
return x;
} void add(int pos){
s[++cur] = str[pos];
int t = getfail(last);
int c = str[pos] - '0';
if(son[t][c] == 0){//这个回文串没有出现过
int o = node(len[t] + 2);
fail[o] = son[getfail(fail[t])][c];
son[t][c] = o;
LL lo = ((sum[llen] - rsum[pos - (len[t] + 2) + 1]) % mod + mod) % mod;
LL hi = rsum[pos + 1];
LL all = lo + hi;
if(all >= mod) all %= mod;
LL t = ((sum[llen] - all) % mod + mod) % mod;
if(t >= mod) t %= mod;
if(llen - pos + 1 - 1 > 0) ans = ans + t * inv10[llen- pos + 1 - 1] % mod;
else
ans = ans + t;
if(ans >= mod) ans %= mod;
}
last = son[t][c];
}
}pt; int main()
{
_10[0] = 1;
for(int i = 1; i <= maxn - 1; i++){
_10[i] = _10[i - 1] * 10;
if(_10[i] >= mod){
_10[i] %= mod;
}
inv10[i] = fermat(_10[i], mod);
}
while(~scanf("%s", str + 1)){
memset(sum, 0, sizeof(sum));
memset(rsum, 0, sizeof(rsum));
ans = 0;
sum[0] = 0;
pt.init();
llen = strlen(str + 1);
for(int i = 1; i <= llen; i++){
sum[i] = sum[i - 1] * 10 + (int)(str[i] - '0');
if(sum[i] >= mod) sum[i] %= mod;
}
rsum[llen + 1] = 0;
for(int i = llen; i >= 1; i--){
rsum[i] = rsum[i + 1] + (int)(str[i] - '0') * _10[llen - i] % mod;
if(rsum[i] >= mod) rsum[i] %= mod;
}
ans = 0;
for(int i = 1; i <= llen; i++){
pt.add(i);
}
printf("%lld\n", (LL)ans % mod);
}
return 0;
}

南京网络赛I-Skr【回文树模板】的更多相关文章

  1. 计蒜客 2018南京网络赛 I Skr ( 回文树 )

    题目链接 题意 : 给出一个由数字组成的字符串.然后要你找出其所有本质不同的回文子串.然后将这些回文子串转化为整数后相加.问你最后的结果是多少.答案模 1e9+7 分析 : 应该可以算是回文树挺裸的题 ...

  2. HDU3948 & 回文树模板

    Description: 求本质不同回文子串的个数 Solution: 回文树模板,学一学贴一贴啊... Code: /*================================= # Cre ...

  3. 2018南京网络赛 - Skr 回文树

    题意:求本质不同的回文串(大整数)的数字和 由回文树的性质可知贡献只在首次进入某个新节点时产生 那么只需由pos和len算出距离把左边右边删掉再算好base重复\(O(n)\)次即可 位移那段写的略微 ...

  4. BZOJ - 3676 回文串 (回文树)

    https://vjudge.net/problem/HYSBZ-3676 题意 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s ...

  5. HDU.5394.Trie in Tina Town(回文树)

    题目链接 \(Description\) 给定一棵\(Trie\).求\(Trie\)上所有回文串 长度乘以出现次数 的和.这里的回文串只能是从上到下的一条链. 节点数\(n\leq 2\times ...

  6. BZOJ.3676.[APIO2014]回文串(回文树)

    BZOJ 洛谷 很久之前写(抄)过一个Hash+Manacher的做法,当时十分懵逼=-= 然而是道回文树模板题. 回文树教程可以看这里(真的挺妙的). 顺便再放上MilkyWay的笔记~ //351 ...

  7. HYSBZ 2160 拉拉队排练(回文树)

    2160: 拉拉队排练 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 825  Solved: 324 [Submit][Status][Discu ...

  8. HYSBZ 3676 回文串 (回文树)

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 1680  Solved: 707 [Submit][Stat ...

  9. BZOJ 3676 回文串(回文树)题解

    题意: 一个回文的价值为长度 * 出现次数,问一个串中的子串的最大回文价值 思路: 回文树模板题,跑PAM,然后计算所有节点出现次数. 参考: 回文串问题的克星--Palindrome Tree(回文 ...

随机推荐

  1. CentOS下的一些基础问题解答

    1. 在/etc/passwd中某一行信息为“Linux01:x:505:505:/home/linux12:/bin/bash”,由此可知哪些信息? 用户名为linux01,需要密码登陆,用户ID为 ...

  2. pacbio 原始下机数据h5 文件简介

    pacbio 采用hdf5文件格式保存原始的下机数据,对于RS 测序系统而言,会产生一个 bas.h5 的文件; 以bas.h5 文件为例,看一下有下机数据中保存了那些信息 h5dump 工具可以用来 ...

  3. 【Java 线程的深入研究2】常用函数说明

    ①sleep(long millis): 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行) ②join():指等待t线程终止. 使用方式. join是Thread类的一个方法,启动线程后直接调用, ...

  4. java bigDecimal and double

    Java BigDecimal和double   BigDecimal是Java中用来表示任意精确浮点数运算的类,在BigDecimal中,使用unscaledValue × 10-scale来表示一 ...

  5. iotop详解

    有时我们希望知道到底哪个进程产生了IO,这个时候就需要iotop这个工具了.它的输出和top命令类似,简单直观.官网:http://guichaz.free.fr/iotop/需要Python 2.5 ...

  6. mysql中" ' "和 " ` "的区别

    http://blog.csdn.net/yang3290325/article/details/3349907

  7. Excel时间格式修改为文本格式

  8. 利用Sharepoint 创建轻量型应用之基本功能配置!

    博客同步课程.假设你想跟着视频学习,请跟着例如以下视频: http://edu.csdn.net/course/detail/2097 1.   点击安装程序,出现的界面先期安装完毕准备工具,准备工具 ...

  9. 50个Android开发技巧(03 自己定义ViewGroup)

    问题:怎样创建一个例如以下图所看到的的布局?                图1 (原文地址:http://blog.csdn.net/vector_yi/article/details/244155 ...

  10. Spring装配Bean的过程

    首先说一个概念:“懒加载” 懒加载:就是我们在spring容器启动的是先不把所有的bean都加载到spring的容器中去,而是在当需要用的时候,才把这个对象实例化到容器中. spring配置文件中be ...