ZOJ 3661 Palindromic Substring(回文树)
Palindromic Substring
Time Limit: 10 Seconds Memory Limit: 65536 KB
In the kingdom of string, people like palindromic strings very much. They like only palindromic strings and dislike all other strings. There is a unified formula to calculate the score
of a palindromic string. The score is calculated by applying the following three steps.
- Since a palindromic string is symmetric, the second half(excluding the middle of the string if the length is odd) is got rid of, and only the rest is considered. For example, "abba" becomes "ab", "aba" becomes "ab" and "abacaba" becomes "abac".
- Define some integer values for 'a' to 'z'.
- Treat the rest part as a 26-based number M and the score is M modulo 777,777,777.
However different person may have different values for 'a' to 'z'. For example, if 'a' is defined as 3, 'b' is defined as 1 and c is defined as 4, then the string "accbcca" has the score
(3×263+4×262+4×26+1) modulo 777777777=55537.
One day, a very long string S is discovered and everyone in the kingdom wants to know that among all the palindromic substrings of S, what the one with the K-th
smallest score is.
Input
The first line contains an integer T(1 ≤ T ≤ 20), the number of test cases.
The first line in each case contains two integers n, m(1 ≤ n ≤ 100000, 1 ≤ m ≤ 20) where n is the length of S and m is
the number of people in the kingdom. The second line is the string S consisting of only lowercase letters. The next m lines each containing 27 integers describes a person in the following format.
Ki va vb ... vz
where va is the value of 'a' for the person, vb is the value of 'b' and so on. It is ensured that the Ki-th smallest palindromic substring
exists and va, vb, ..., vz are in the range of [0, 26). But the values may coincide.
Output
For each person, output the score of the K-th smallest palindromic substring in one line. Print a blank line after each case.
Sample Input
3
6 2
abcdca
3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
7 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
4 10
zzzz
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
9 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
10 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14
51 4
abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba
1 1 3 3 25 20 25 21 7 0 9 7 3 16 15 14 19 5 19 19 19 22 8 23 2 4 1
25 1 3 3 25 20 25 21 7 0 9 7 3 16 15 14 19 5 19 19 19 22 8 23 2 4 1
26 1 3 3 25 20 25 21 7 0 9 7 3 16 15 14 19 5 19 19 19 22 8 23 2 4 1
76 1 3 3 25 20 25 21 7 0 9 7 3 16 15 14 19 5 19 19 19 22 8 23 2 4 1
Sample Output
1
620 14
14
14
14
14
14
14
378
378
378 0
9
14 733665286 回文树#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <stdio.h>
#include <math.h> using namespace std;
typedef long long int LL;
const int maxn=1e5+5;
const int mod=777777777;
char str[maxn];
int n,m;
LL k;
int a[26];
LL pow(int x)
{
LL sum=1;
LL n=26;
for(x;x;x>>=1)
{
if(x&1)
sum=(sum*n)%mod;
n=(n*n)%mod;
}
return sum;
}
struct Node
{
LL num;
LL sum;
}c[maxn];
int cmp(Node a,Node b)
{
return a.sum<b.sum;
}
struct Tree
{
int next[maxn][26];
int fail[maxn];
LL num[maxn];
int cnt[maxn];
int len[maxn];
int s[maxn];
int last,p,n;
int new_node(int x)
{
memset(next[p],0,sizeof(next[p]));
cnt[p]=0;
num[p]=0;
len[p]=x;
return p++;
}
void init()
{
p=0;
new_node(0);
new_node(-1);
last=0;
n=0;
s[0]=-1;
fail[0]=1;
}
int get_fail(int x)
{
while(s[n-len[x]-1]!=s[n])
x=fail[x];
return x;
}
int add(int x)
{
x-='a';
s[++n]=x;
int cur=get_fail(last);
if(!(last=next[cur][x]))
{
int now=new_node(len[cur]+2);
fail[now]=next[get_fail(fail[cur])][x];
next[cur][x]=now;
num[now]=(num[cur]+((LL)pow((len[cur]+1)/2)*a[x])%mod)%mod;
last=now;
}
cnt[last]++;
return 1;
}
void count()
{
for(int i=p-1;i>=0;i--)
cnt[fail[i]]+=cnt[i];
}
void fun()
{
count();
int cot=0;
for(int i=2;i<p;i++)
{
c[cot].num=cnt[i];
c[cot++].sum=num[i];
}
sort(c,c+cot,cmp);
int i;
for( i=0;i<cot;i++)
{
if(k>c[i].num)
{
k-=c[i].num;
}
else
break;
}
printf("%d\n",c[i].sum);
}
}tree;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
scanf("%s",str);
for(int i=1;i<=m;i++)
{
scanf("%lld",&k);
for(int j=0;j<26;j++)
scanf("%d",&a[j]);
tree.init();
for(int j=0;j<n;j++)
{
tree.add(str[j]);
}
tree.fun();
}
cout<<endl;
}
return 0;
}
ZOJ 3661 Palindromic Substring(回文树)的更多相关文章
- LeetCode 5. Longest Palindromic Substring & 回文字符串
Longest Palindromic Substring 回文这种简单的问题,在C里面印象很深啊.希望能一次过. 写的时候才想到有两种情况: 454(奇数位) 4554(偶数位) 第1次提交 cla ...
- HDU5658:CA Loves Palindromic (回文树,求区间本质不同的回文串数)
CA loves strings, especially loves the palindrome strings. One day he gets a string, he wants to kno ...
- HDU 5658 CA Loves Palindromic(回文树)
CA Loves Palindromic Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/O ...
- Palindromic Tree 回文自动机-回文树 例题+讲解
回文树,也叫回文自动机,是2014年被西伯利亚民族发明的,其功能如下: 1.求前缀字符串中的本质不同的回文串种类 2.求每个本质不同回文串的个数 3.以下标i为结尾的回文串个数/种类 4.每个本质不同 ...
- 回文树 Palindromic Tree
回文树 Palindromic Tree 嗯..回文树是个什么东西呢. 回文树(或者说是回文自动机)每个节点代表一个本质不同的回文串. 首先它类似字典树,每个节点有SIGMA个儿子,表示对应的字母. ...
- 回文树&后缀自动机&后缀数组
KMP,扩展KMP和Manacher就不写了,感觉没多大意思. 之前感觉后缀自动机简直可以解决一切,所以不怎么写后缀数组. 马拉车主要是通过对称中心解决问题,有的时候要通过回文串的边界解决问题 ...
- 回文树练习 Part1
URAL - 1960 Palindromes and Super Abilities 回文树水题,每次插入时统计数量即可. #include<bits/stdc++.h> using ...
- Gym - 101806Q:QueryreuQ(回文树)
A string is palindrome, if the string reads the same backward and forward. For example, strings like ...
- 南京网络赛I-Skr【回文树模板】
19.32% 1000ms 256000K A number is skr, if and only if it's unchanged after being reversed. For examp ...
随机推荐
- 从1KW条数据中筛选出1W条最大的数
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...
- 区分SQL Server关联查询之inner join,left join, right join, full outer join并图解
1.from A inner join B on A.ID=B.ID :两表都有的记录才列出 A表: ID Name B表: ID Clas ...
- C语言 fork
/* *@author cody *@date 2014-08-12 *@description */ /* #include <sys/types.h> #include <uni ...
- scut客户端心跳超时和客户端断开测试
1.断开的消息触发后,依然会触发超时 2.触发超时不会触发断开 3.超时会触发多次,断开只触发一次 超时不是很准确,好像有时候不会触发.如果要判断玩家是否下线,可以用最后一次心跳时间判断
- python学习之with...as语句
python中的with...as...语句类似于try...finally...语句: # -*- coding: utf-8 -*- # """ with...as. ...
- JavaScript学习日志(2)
javascript数据类型: 字符串string.数字number.未定义Undefined.空Null.布尔Boolean.数组Array.对象Object.javascript对象: 对象由花括 ...
- 某某水表-M1卡数据算法分析
# 某某水表-M1卡数据算法分析 ## 卡片数据-----------------------------扇区数据 | 金额:--- |:---13EC 0000 0000 0000 0000 000 ...
- spring-jmx.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 爬虫 (4)- Selenium与PhantomJS(chromedriver)与爬取案例
Selenium文档 Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同是Selenium 可以直接运行在浏览器 ...
- EasyUI项目学习
介绍easyui的使用,主要包括以下组件 布局面板 - layout 可伸缩面板 - accordion 选项卡 - tabs 控制面板 - panel 窗口 - window 对话框 - dialo ...