luogu P5329 [SNOI2019]字符串
显然要写一个排序,那只要考虑cmp函数怎么写就行了.第\(i\)个字符串和第
\(j\)个,首先前\(min(i,j)-1\)个字符是相同的,然后就是要比较后缀\(min(i,j)\)和\(min(i,j)+1\),先求lcp(要对\(max(i,j)-min(i,j)\)取\(min\)),如果两个后缀往后跳lcp的位置字符不一样就可以得到结果了.
然后可以用SA求lcp 然后我T了,但是可以发现所有lcp都是相邻两个后缀的,所以这个可以\(O(n)\)递推
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db double
using namespace std;
const int N=2e6+10;
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
char cc[N];
int /*sa[N],rk[N],wr[N],wx[N],bk[N],*/he[N]/*,mi[N][21],L2[N]*/,n,an[N];
/*void inii()
{
int sz=128,p=0,j=1;
for(int i=1;i<=n;++i) ++bk[rk[i]=cc[i]];
for(int i=1;i<=sz;++i) bk[i]+=bk[i-1];
for(int i=n;i;--i) sa[bk[rk[i]]--]=i;
while(p<n)
{
int tp=0;
for(int i=n-j+1;i<=n;++i) wx[++tp]=i;
for(int i=1;i<=n;++i) if(sa[i]>j) wx[++tp]=sa[i]-j;
for(int i=1;i<=n;++i) wr[i]=rk[wx[i]];
for(int i=1;i<=sz;++i) bk[i]=0;
for(int i=1;i<=n;++i) ++bk[wr[i]];
for(int i=1;i<=sz;++i) bk[i]+=bk[i-1];
for(int i=n;i;--i) sa[bk[wr[i]]--]=wx[i];
for(int i=1;i<=n;++i) wr[i]=rk[i];
rk[sa[1]]=p=1;
for(int i=2;i<=n;++i) rk[sa[i]]=p+=!(wr[sa[i]]==wr[sa[i-1]]&&wr[sa[i]+j]==wr[sa[i-1]+j]);
sz=p,j<<=1;
}
for(int i=1;i<=n;++i)
{
if(he[rk[i-1]]) he[rk[i]]=he[rk[i-1]]-1;
int j=sa[rk[i]-1];
while(cc[i+he[rk[i]]]==cc[j+he[rk[i]]]) ++he[rk[i]];
}
for(int i=2;i<=n;++i) L2[i]=L2[i>>1]+1;
for(int i=1;i<=n;++i) mi[i][0]=he[i];
for(int j=1;j<=L2[n];++j)
for(int i=1;i+(1<<j)-1<=n;++i)
mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);
}
int lcp(int i,int j)
{
if(i==j) return n;
i=rk[i],j=rk[j];
if(i>j) swap(i,j);
++i;
int z=L2[j-i+1];
return min(mi[i][z],mi[j-(1<<z)+1][z]);
}*/
bool cmp(int i,int j)
{
/*int ii,jj;
if(i<j) ii=i+1,jj=i;
else ii=j,jj=j+1;
int len=lcp(ii,jj);
if(ii<i) len=min(len,i-ii);
if(jj<j) len=min(len,j-jj);
ii+=len,jj+=len;
ii+=ii==i,jj+=jj==j;
if(cc[ii]!=cc[jj]) return cc[ii]<cc[jj];
return i<j;*/
int ii=min(i,j),lm=max(i,j)-ii,len=he[ii+1];
if(len>=lm) return i<j;
return (cc[ii+len]<cc[ii+1+len])^(i<j);
}
int main()
{
n=rd();
scanf("%s",cc+1);
for(int i=2;i<=n;++i)
{
if(he[i-1]) he[i]=he[i-1]-1;
while(cc[i+he[i]]==cc[i-1+he[i]]) ++he[i];
}
for(int i=1;i<=n;++i) an[i]=i;
sort(an+1,an+n+1,cmp);
for(int i=1;i<=n;++i) printf("%d ",an[i]);
return 0;
}
luogu P5329 [SNOI2019]字符串的更多相关文章
- [洛谷P5329][SNOI2019]字符串
题目大意:给一个长度为$n$的字符串$s$,字符串$p_i$为字符串$s$去掉第$i$个字符后形成的字符串.请给所有字符串$p_i$排序(相同字符串按编号排序) 题解:先去掉所有连续相同字符,因为它们 ...
- 洛谷$P5329\ [SNOI2019]$字符串 字符串
正解:字符串 解题报告: 传送门$QwQ$ 有两个很妙的方法,分别港下$QwQ$ 首先为了表示方便,这里和题面一样设$s_i$表示去掉第$i$个字母得到的字符串.另设$lcp(i,j)$表示$suf_ ...
- 【LOJ#3095】[SNOI2019]字符串(后缀数组)
[LOJ#3095][SNOI2019]字符串(后缀数组) 题面 LOJ 题解 首先画图看看如何比较两个串的大小,发现这个东西等价于求两个相邻的后缀的\(LCP\). 一个做法是求出\(SA\),然后 ...
- 题解 P5329 【[SNOI2019]字符串】
用栈的做法来水一发. 首先我们有一个暴力的做法,枚举每个被删除的字符,然后排序输出,时间复杂度:$ O ( N \times N \times LogN ) $ . 然后我们观察一下数据,发现有一个数 ...
- Luogu 1071 - 潜伏者 - [字符串]
题目链接:https://www.luogu.org/problemnew/show/P1071 题解: 模拟就完事儿了. 注意failed的情况有:出现一个 $f[x]$ 对应多个值:存在两个不同的 ...
- [SNOI2019]字符串
名称:字符串 来源:2019年陕西省选 题目内容 传送门 洛谷(P5392) 题目描述 给出一个长度为$n$的由小写字母组成的字符串$a$,设其中第$i$个字符为$a_i(1≤i≤n)$. 设删掉第$ ...
- luogu P4302 [SCOI2003]字符串折叠
题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS-S(X个S). 如果A = A', B = ...
- Luogu P2679 子串(字符串+dp)
P2679 子串 题意 题目描述 有两个仅包含小写英文字母的字符串\(A\)和\(B\). 现在要从字符串\(A\)中取出\(k\)个互不重叠的非空子串,然后把这\(k\)个子串按照其在字符串\(A\ ...
- luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
LINK:字符串树 先说比较简单的正解.由于我没有从最简单的考虑答案的角度思考 所以... 下次还需要把所有角度都考察到. 求x~y的答案 考虑 求x~根+y~根-2*lca~根的答案. 那么问题变成 ...
随机推荐
- Selenium 上手:Selenium扫盲区
Selenium 自述Selenium 是由Jason Huggins软件工程师编写的一个开源的浏览器自动化测试框架.主要用于测试自动化Web UI应用程序. Selenium 工作原理通过编程语言( ...
- 模板引擎ejs的include方法
html无法include header.ejs footer.ejs 最后用 user.ejs在首尾include
- xml文件中 xmlns xmlns:xsi 等解释
http://bbs.csdn.NET/topics/390751819 maven 的 pom.xml 开头是下面这样的 <project xmlns="http://maven.a ...
- XML文件解析!!!
在java jdk中解析XMl文件使用 org.w3c.dom.Document工具 一下是写入全程: import java.io.File; import java.io.IOExceptio ...
- nginx排查502错误
排查502错误1.查看/usr/local/nginx/conf/nginx.conf从而知道其错误日志在哪.重点查看其错误日志.2.如果是/tmp/dd.sock2017/05/01 18:48:3 ...
- 中国MOOC_零基础学Java语言_第2周 判断
浮点数判断大小 public class Main { public static void main(String[] args) { double a = 1.0; double b = 0.1 ...
- flultter listview异常type '(BuildContext, int) => dynamic' is not a subtype of type '(BuildContext, int) => Widget'
type '(BuildContext, int) => dynamic' is not a subtype of type '(BuildContext, int) => Widget' ...
- Java中个容器的对比
List: 有序,列表存储,元素可重复 Set: 无序,元素不可重复 Map:无序,元素可重复,key不能重复 LinkedList :链表,删除和添加效率很高,随机访问效率较ArrayList类低, ...
- Android - Unable to add window android.view.ViewRootImpl$W@6518342 -- permission denied for window type 2133
因为跟博主碰到了一样的问题,所以记录一下分析原理 原文链接:https://www.jianshu.com/p/b0364074288a 首先,先介绍下背景环境,第一,是Android7.0,其次,要 ...
- 【Qt开发】事件循环与线程 一
事件循环与线程 一 初次读到这篇文章,译者感觉如沐春风,深刻体会到原文作者是花了很大功夫来写这篇文章的,文章深入浅出,相信仔细读完原文或下面译文的读者一定会有收获. 由于原文很长,原文作者的行文思路是 ...