• 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. adb调试功能

    参考: http://www.cnblogs.com/meil/archive/2012/05/24/2516055.html http://www.biemmeitalia.net/blog/and ...

  2. PHP 初学

    虚拟目录和虚拟主机的关系?虚拟主机可以设置多个,虚拟目录呢? 以为phpstorm和Intellij一样,结果不是!它直接将所有内容上传(部署)到服务器即可,不像Intellij那样还调用服务器?? ...

  3. 应当将指针变量用“==”或“!=”与 NULL 比较

    应当将指针变量用“==”或“!=”与 NULL 比较. 指针变量的零值是“空”(记为 NULL). 尽管 NULL 的值与 0 相同,但是两者意义不 同. 假设指针变量的名字为 p,它与零值比较的标准 ...

  4. C#有关的vshost、exe、config格式说明

    vshost.exe.config是程序运行时的配置文本 exe.config是程序运行后会复制到vshost.exe.config app.config是在vshost.exe.config和exe ...

  5. ulimit设置句柄数

    这几天在做一个性能测试,写了一个模拟发送http的程序.模拟100并发的情况下,随机发http get的请求.放到服务器上运行一段时间抛出Too many open files的异常. 这几天在做一个 ...

  6. 动态提交使用jQuery 完成ajax 文件下载----后端php

    1.js代码 // Ajax 文件下载 //当不用传参时,可以将data去掉 jQuery.download = function(url, data, method){ // 获得url和data ...

  7. 属性编辑器,即PropertyEditor-->Spring IoC

    在Spring配置文件里,我们往往通过字面值为Bean各种类型的属性提供设置值:不管是double类型还是int类型,在配置文件中都对应字符串类型的字面值.BeanWrapper填充Bean属性时如何 ...

  8. JQuery 选择器 xpath 语法应用

    比如下面html代码 <ul> <li class="aaaa" title="ttt">li-1</li> <li ...

  9. 你与论文达人只差一个MathType的距离

    在理工类的论文文档中总是少不了数学公式的出现,各种符号夹杂在期间导致论文在编写时总是会出现各种各样的问题.但是这些问题在论文达人们手中全都不是事儿!分分钟搞定你数学公式上出现的问题!论文达人们是怎么搞 ...

  10. VC++ :实现简单的文件拖放(Drag and Drop)功能

    1) VC++ 6.0 新建一个基于对话框的MFC的工程,取名MfcDropFiles: 2) 去除默认的控件,包括确定/取消按钮,以及一个静态文本: 3) 在对话框空白区域拖放一个ListBox控件 ...