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. Js日常笔记之this

    在javascript中自己创建构造函数时可以利用this来指向新创建的对象上.这样就可以避免函数中的this指向全局了,如下 var x = 2; function test(){ this.x = ...

  2. selenium2.0 --常用函数2

    新建实例driver = webdriver.Chrome() 1.获取当前页面的Url函数 方法:current_url 实例: driver.current_url 2.获取元素坐标 方法:loc ...

  3. PHP 常用函数回顾

    array_change_key_case — 返回字符串键名全为小写或大写的数组array_chunk — 将一个数组分割成多个array_combine — 创建一个数组,用一个数组的值作为其键名 ...

  4. Lintcode---二叉树的层次遍历(原型)

    给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问) 您在真实的面试中是否遇到过这个题? Yes 样例 给一棵二叉树 {3,9,20,#,#,15,7} : 3 / \ 9 20 / \ 15 ...

  5. unity, 什么时候用静态类,什么时候用单例

    如果没有成员变量,或者成员变量都是常量,则用静态类. 如果有成员变量,则用单例.(以便让成员变量有初始化机会). //静态类 public class CmyFuncs{ public float m ...

  6. Unix删除当前目录可执行文件

    On GNU versions of find you can use -executable: find . -type f -executable -printFor BSD versions o ...

  7. Objective-C_Block

    一.Block语法 Block:块语法,本质上是匿名函数(没有名称的函数),Block变量存放函数的实现,通过Block变量能直接调⽤函数.标准C里面没有Block.C语言的后期扩展版本号.加⼊了匿名 ...

  8. ecmall程序结构图与数据库表分析

    以下是ecmall的程序结构图,看了这张图,我们可以清楚的知道ecmall的程序结构. ECMALL数据库主要表如下所示: ecm_acategory:存放的是商城的文章分类.ecm_address: ...

  9. CCNA2.0笔记_IP连接排错

    IPv4 路由排错 ping tracert traceroute telnet show mac address-table show interfaces fastEthernet 0/1 sho ...

  10. hdu6000 Wash 巧妙地贪心

    /** 题目:hdu6000 Wash 巧妙地贪心 链接:https://vjudge.net/contest/173364#problem/B 转自:http://blog.csdn.net/ove ...