题目链接:

Suffix

Consider n given non-empty strings denoted by s1 , s2 , · · · , sn . Now for each of them, you need to select a corresponding suffix, denoted by suf1, suf2, · · · , sufn. For each string si, the suffix sufi is a non-empty substring whose right endpoint is the endpoint of the entire string. For instance, all suffixes of the string “jiangsu” are “u”, “su”, “gsu”, “ngsu”, “angsu”, “iangsu” and itself.

All selected suffixes could assemble into a long string T = suf_1suf​1​​ + suf_2suf​2​​ + · · · + suf_nsuf​n​​ . Here plus signs indicate additions of strings placing the latter at the tail of the former. Your selections of suffixes would determine the lexicographical order of T . Now, your mission is to find the one with minimum lexicographical order.

Here is a hint about lexicographical order. To compare strings of different lengths, the shorter string is usually padded at the end with enough “blanks” which is a special symbol that is treated as smaller than every letters.

Input

The first line of input contains an integer T which is the total number of test cases. For each case, the first line contains an positive integer n. Each of the following n lines contains a string entirely in lowercase, corresponding to s_1s​1​​ , s_2s​2​​ , · · · , s_ns​n​​ . The summation of lengths of all strings in input is smaller or equal to 500000.

Output

For each test case, output the string T with minimum lexicographical order.

样例输入

3
3
bbb
aaa
ccc
3
aba
aab
bab
2
abababbaabbababba
abbabbabbbababbab

样例输出

baaac
aaabab
aab 题意:
n个字符串每个选择一个后缀依次连接,值得新得到的字符串字典序最小; 思路:
可以发现应该从后往前,把后面得到的字符串连接到第i个后面,再求这个的最小字典序的后缀,我写后缀数组T,所以采用hash+二分寻找和当前ans的lcp,然后比较lcp的下一位更新ans AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
const int maxn=5e5+10;
const int x=123;
char s[maxn],tep[maxn],ans[maxn];
int le[maxn],anslen,p;
LL H[maxn],xp[maxn];
inline void init()
{
xp[0]=1;
for(int i=1;i<maxn;i++)xp[i]=xp[i-1]*x;
}
int check(int len)
{
LL u=H[p]-H[p-len]*xp[len],v=H[anslen]-H[anslen-len]*xp[len];
if(u!=v)return 0;
return 1;
}
int main()
{
init();
int T;scanf("%d",&T);
while(T--)
{
int n;
scanf("%d ",&n);
int sum=0;
for(int i=1;i<=n;++i)
{
gets(s);
le[i]=strlen(s);
for(int j=0;j<le[i];j++)tep[sum+j]=s[j];
sum=sum+le[i];
}
anslen=1,p=1;
H[0]=0;ans[0]=0;
for(int i=n;i>0;i--)
{
for(int j=0;j<le[i];j++,anslen++)
{
ans[anslen]=tep[--sum];
H[anslen]=H[anslen-1]*x+(ans[anslen]-'a');
if(j==0){p=anslen;continue;}
int l=0,r=p;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))l=mid+1;
else r=mid-1;
}
if(l<p+1&&ans[anslen-l+1]<ans[p-l+1])p=anslen;
}
anslen=p+1;
}
for(int i=p;i>0;i--)printf("%c",ans[i]);puts("");
}
return 0;
}

  

Suffix(hash+lcp+二分)的更多相关文章

  1. Gym - 100570E:Palindrome Query (hash+BIT+二分维护回文串长度)

    题意:给定字符串char[],以及Q个操作,操作有三种: 1:pos,chr:把pos位置的字符改为chr 2:pos:问以pos为中心的回文串长度为多长. 3:pos:问以pos,pos+1为中心的 ...

  2. bzoj 1014 LCP 二分 Hash 匹配

    求同一字符串的两个后缀的最长公共前缀. 将字符串按位置放到Splay中维护(每个节点还维护一下该子树的hash),然后二分前缀的长度,用splay计算出指定范围的hash,按hash是否相等来判断是否 ...

  3. Hash(LCP) || 后缀数组 LA 4513 Stammering Aliens

    题目传送门 题意:训练指南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std ...

  4. [poj2785]4 Values whose Sum is 0(hash或二分)

    4 Values whose Sum is 0 Time Limit: 15000MS Memory Limit: 228000K Total Submissions: 19322 Accepted: ...

  5. bzoj1014 火星人 (hash+splay+二分答案)

    求公共前缀的问题可以用hash+二分来解决,但这个是动态的,所以我们用平衡树来维护区间的hash值 复杂度$O(mlog^2n)$ #include<bits/stdc++.h> #def ...

  6. 后缀数组LCP + 二分 - UVa 11107 Life Forms

    Life Forms Problem's Link Mean: 给你n个串,让你找出出现次数大于n/2的最长公共子串.如果有多个,按字典序排列输出. analyse: 经典题. 直接二分判断答案. 判 ...

  7. nyoj--86--找球号(一)(hash&&set&&二分)

    找球号(一) 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 在某一国度里流行着一种游戏.游戏规则为:在一堆球中,每个球上都有一个整数编号i(0<=i<=10 ...

  8. 51nod(1089 最长回文子串 V2)(hash 加二分)

    1089 最长回文子串 V2(Manacher算法)   回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串. 输入一个字符串Str,输出Str里最长回文子串的长度.   输入 ...

  9. uvalive 4513 Stammering Aliens

    题意:给你一个串,问期中至少出现m次的最长子串及其起始位置的坐标. 思路:hash+LCP+二分答案 #include<cstdio> #include<cstring> #i ...

随机推荐

  1. MYSQL数据库里面的所有密码批量MD5加密

    如果你的字段够长度的话:UPDATE users SET password = MD5(password);如果长度不够,可以先增加长度后再做,或者多建一列,完成后删除原来的列!(如passwd)UP ...

  2. Maven项目mybatis Invalid bound statement (not found)解决方法

    最近因为工作需要,要学习mybatis框架.在添加好一些依赖之后,通过mybatis进行数据库的crud操作.但是在测试的时候总是报mybatis:Invalid bound statement (n ...

  3. POJ 2186 Popular Cows(强连通分量Kosaraju)

    http://poj.org/problem?id=2186 题意: 一个有向图,求出点的个数(任意点可达). 思路: Kosaraju算法的第一次dfs是后序遍历,而第二次遍历时遍历它的反向图,从标 ...

  4. 1.JSON 转换对象失败问题 2.spring注入失效

    今天做项目中将一个json 字符串转换为对象,但结果怎么都转换不了!——————最后发现问题,原来是因为这个类我给他添加了带参数的构造器!导致转换失败! 在添加一个无参的构造器就好了! 第二个:今天调 ...

  5. 公众号菜单中的click

    $params = [ 'button' => [ [ 'type'=>'click', 'name'=>'就送帽子', 'key'=>'V1001_PRESENT', ], ...

  6. Memcached stats sizes 命令

    Memcached stats sizes 命令用于显示所有item的大小和个数. 该信息返回两列,第一列是 item 的大小,第二列是 item 的个数. 语法: stats sizes 命令的基本 ...

  7. Angular如何给动态生成的元素绑定事件

    在AngularJS中,操作DOM一般在指令中完成,事件监听机制是在对于已经静态生成的dom绑定事件,而如果在指令中动态生成了DOM节点,动态生成的节点不会被JS事件监听. 举例来说: angular ...

  8. 超详细!mac flutter 创建过程及遇到的问题

    虽然网上有教程,但是过程中遇到些问题,这些问题教程里并没有,所以写这个文章记录一下. 1.打开终端 2.clone flutter 命令: git clone -b beta https://gith ...

  9. Art-Template模板引擎(原生写法与简洁写法)

    模板引擎:把js数据转换成html需要的页面,这就是模板引擎需要做的事     • native原生语法     1. 准备数据     2. 把数据转化成html格式的字符串 使用模板引擎 artT ...

  10. 使用VMware出现的各种问题

    ifconfig命令无效 解决办法:yum install net-tools ping不通 cd /etc/sysconfig/network-scripts ls查看所有文件名称,找到ifcfg- ...