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.

  1. 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".
  2. Define some integer values for 'a' to 'z'.
  3. 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(回文树)的更多相关文章

  1. LeetCode 5. Longest Palindromic Substring & 回文字符串

    Longest Palindromic Substring 回文这种简单的问题,在C里面印象很深啊.希望能一次过. 写的时候才想到有两种情况: 454(奇数位) 4554(偶数位) 第1次提交 cla ...

  2. HDU5658:CA Loves Palindromic (回文树,求区间本质不同的回文串数)

    CA loves strings, especially loves the palindrome strings. One day he gets a string, he wants to kno ...

  3. HDU 5658 CA Loves Palindromic(回文树)

    CA Loves Palindromic Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/O ...

  4. Palindromic Tree 回文自动机-回文树 例题+讲解

    回文树,也叫回文自动机,是2014年被西伯利亚民族发明的,其功能如下: 1.求前缀字符串中的本质不同的回文串种类 2.求每个本质不同回文串的个数 3.以下标i为结尾的回文串个数/种类 4.每个本质不同 ...

  5. 回文树 Palindromic Tree

    回文树 Palindromic Tree 嗯..回文树是个什么东西呢. 回文树(或者说是回文自动机)每个节点代表一个本质不同的回文串. 首先它类似字典树,每个节点有SIGMA个儿子,表示对应的字母. ...

  6. 回文树&后缀自动机&后缀数组

    KMP,扩展KMP和Manacher就不写了,感觉没多大意思.   之前感觉后缀自动机简直可以解决一切,所以不怎么写后缀数组.   马拉车主要是通过对称中心解决问题,有的时候要通过回文串的边界解决问题 ...

  7. 回文树练习 Part1

    URAL - 1960   Palindromes and Super Abilities 回文树水题,每次插入时统计数量即可. #include<bits/stdc++.h> using ...

  8. Gym - 101806Q:QueryreuQ(回文树)

    A string is palindrome, if the string reads the same backward and forward. For example, strings like ...

  9. 南京网络赛I-Skr【回文树模板】

    19.32% 1000ms 256000K A number is skr, if and only if it's unchanged after being reversed. For examp ...

随机推荐

  1. SQL外键约束

    1.查询表已有的外键 select name from sys.foreign_key_columns f join sys.objects o on f.constraint_object_id=o ...

  2. 简单的刚開始学习的人配置Android SDK+ADT+Eclipse

    1.下载JDK.Android SDK和Eclipse(Eclipse 版本号最好新一些) 注意:下载的SDK最好和后面的ADT配套,否则Eclipse可能会报错. 如:SDK 21.0.1 相应 A ...

  3. Rabbitmq消息队列(五) 路由Routing

    1.简介 在以前一章中,我们可以把一个消息广播给多个接收者.在这一章中,我们会增加一个功能:接收者能够只接收订阅消息中的一个子集. 2.绑定 在我们将交换机和队列进行绑定的时候,我们可以添加一个额外的 ...

  4. Java多线程之内置锁与显示锁

    Java中具有通过Synchronized实现的内置锁,和ReentrantLock实现的显示锁,这两种锁各有各的好处,算是互有补充,今天就来做一个总结. Synchronized 内置锁获得锁和释放 ...

  5. 544. Top k Largest Numbers【medium】

    Given an integer array, find the top k largest numbers in it.   Example Given [3,10,1000,-99,4,100] ...

  6. Redis-ha(sentinel)搭建

    服务器描述:本次搭建是用来测试,所以是在一台服务器上搭建三个redis服务(一主两从) 服务角色 端口 Redis.conf名称 sentinel配置文件名称 sentinel端口 redis日志路径 ...

  7. datatables 相关文章

    http://blog.csdn.net/zhu_xiao_yuan/article/details/51252300 datatables参数配置详解  http://blog.csdn.net/j ...

  8. linux学习笔记2---命令cd

    Linux cd 命令可以说是Linux中最基本的命令语句,其他的命令语句要进行操作,都是建立在使用 cd 命令上的.cd命令比较简单,但是有一些技巧还是值得学习的. 所以,学习Linux 常用命令, ...

  9. QBC运算符含义

    HQL运算符                   QBC运算符                      含义      =                     Restrictions.eq() ...

  10. [转]Mac系统安装软件提示软件已损坏的解决办法

    很多朋友下载本站提供的Mac软件资源,安装提示“xxx软件已损坏,打不开,您应该将它移到废纸篓”的提示,其实并不是软件本身有问题,而是Mac系统的一个安全机制问题,按照如下方法操作,即可打开并安装本站 ...