洛谷1368 工艺 - 后缀数组

题意:输入一个串,通过环形变换使它最小。(n<=300000)

裸的后缀排序啊!

(卡常把命都卡掉了)

后缀数组记得开大啊

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 int x[1200005],y[1200005],u[1200005],v[1200005],r[1200005],o[1200005],n,m=700000;
 5 int str[600005],buf[600005];
 6
 7 int main(){
 8     scanf("%d",&n);
 9     for(int i=1;i<=n;i++) scanf("%d",&str[i]),buf[i]=str[i];
10     sort(buf+1,buf+n+1);
11     for(int i=1;i<=n;i++) str[i]=lower_bound(buf+1,buf+n+1,str[i])-buf;
12     for(int i=1;i<=n;i++) str[i+n]=str[i];
13
14     n*=2;
15
16     for(register int i=1;i<=n;i++) u[str[i]]++;
17     for(register int i=1;i<=m;i++) u[i]+=u[i-1];
18     for(register int i=n;i>=1;i--) x[u[str[i]]--]=i;
19     r[x[1]]=1;
20     for(int i=2;i<=n;i++) r[x[i]]=r[x[i-1]]+(str[x[i]]!=str[x[i-1]]);
21
22     for(int l=1;r[x[n]]<n;l<<=1) {
23         memset(u,0,sizeof u);
24         memset(v,0,sizeof v);
25         memcpy(o,r,sizeof r);
26         for(register int i=1;i<=n;i++) u[r[i]]++, v[r[i+l]]++;
27         for(register int i=1;i<=n;i++) u[i]+=u[i-1], v[i]+=v[i-1];
28         for(register int i=n;i>=1;i--) y[v[r[i+l]]--]=i;
29         for(register int i=n;i>=1;i--) x[u[r[y[i]]]--]=y[i];
30         r[x[1]]=1;
31         for(register int i=2;i<=n;i++)
32             r[x[i]]=r[x[i-1]]+((o[x[i]]!=o[x[i-1]])||(o[x[i]+l]!=(o[x[i-1]+l])));
33     }
34
35     for(int i=1;i<=n;i++)
36         if(x[i]<=n/2) {
37             for(register int j=1;j<=n/2;j++) printf("%d ",buf[str[x[i]+j-1]]);
38             return 0;
39         }
40 }

原文地址:https://www.cnblogs.com/mollnn/p/8449690.html

时间: 2024-08-02 20:41:52

洛谷1368 工艺 - 后缀数组的相关文章

[模板]洛谷T3368 树状数组 模板2

1.对于区间修改: 直接修改数组c[],即进行n次add,肯定会TLE: 于是在此引入一个新数组:addv[],addv[i]指的是以结点i为根的树的所有元素加上addv[i]. 设将区间[a,b]中每个数加上x, 则只需自b向左,将相应的addv[]加上x,再自a-1向左,将多修改的结点的addv[]减去x即可. 2.对于单点查询: 设查询结点i,则其原值为: (以结点i为根的树的所有元素的和)-(此树中除结点i之外的所有节点的和): 然后从结点i向树根遍历,将遍历到的节点的addv[]值加给

洛谷-小鱼比可爱-数组

题目描述 Description 人比人,气死人:鱼比鱼,难死鱼.小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度.参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度都不一样.由于所有的鱼头都朝向左边,所以每只鱼只能看见在它左边的鱼的可爱程度,它们心里都在计算,在自己的眼力范围内有多少只鱼不如自己可爱呢.请你帮这些可爱但是鱼脑不够用的小鱼们计算一下. 输入输出格式 Input/outpu

[模板]洛谷T3374 树状数组 模板1

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<ctime> 6 #include<cstdlib> 7 8 #include<algorithm> 9 #include<string> 10 #include<stack> 11 #include<queue>

【BZOJ2882】工艺(后缀数组)

[BZOJ2882]工艺(后缀数组) 题面 BZOJ权限题,我爱良心洛谷 题解 最容易的想法: 把字符串在后面接一份 然后求后缀数组就行了... #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map>

洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N x N 的方格.输入数据中包括有树的方格的列表.你的任务是计算并输出,在他的农场中,不需要砍树却能够修建的最大正方形牛棚.牛棚的边必须和水平轴或者垂直轴平行. EXAMPLE 考虑下面的方格,它表示农夫约翰的农场,‘.'表示没有树的方格,‘#'表示有树的方格 1 2 3 4 5 6 7 8 1 .

洛谷P1449 后缀表达式 栈 模拟 字符串

洛谷P1449 后缀表达式 栈 模拟 字符串 栈模拟一下 碰到 . 如果输入的是数字就把数字放进栈中 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <cstdlib> 5 #include <string> 6 #include <algorithm> 7 #include <iomanip> 8 #include <io

[洛谷P1198/BZOJ1012][JSOI2008] 最大数 - 树状数组/线段树?

其实已经学了树状数组和线段树,然而懒得做题,所以至今没写多少博客 Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当前数列的长度.(L>=0) 2. 插入操作. 语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾. 限制:n是整数(可能为负数)并且在长整

洛谷3919:可持久化数组——题解

https://www.luogu.org/problemnew/show/P3919 如题,你需要维护这样的一个长度为 N 的数组,支持如下几种操作 在某个历史版本上修改某一个位置上的值 访问某个历史版本上的某一位置的值 此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本.版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组) 这题题意看错了就很伤……操作2新建的版本是它所询问的历史版本emmm…… 以及各种小错误,int没retur

洛谷P3380 【模板】二逼平衡树(树套树,树状数组,线段树)

洛谷题目传送门 emm...题目名写了个平衡树,但是这道题的理论复杂度最优解应该还是树状数组套值域线段树吧. 就像dynamic ranking那样(蒟蒻的Sol,放一个link骗访问量233) 所有的值(包括初始a数组,操作1.3.4.5的k)全部先丢进去离散化 对于1操作查比它小的数,挑log棵线段树,找区间小于这个数的个数+1,这个还比较好像 操作2就是dynamic ranking,log棵线段树一起加减,像静态主席树求第k小一样跳,操作3 dynamic ranking里也有 操作4先