题意:

给一个长度为n的字符串s[0..n-1],但i的后继不再是i+1,而是(i*i+1)%n,求所有长度为n的“子串”中,字典序最大的是谁

n<=150000,s[i]=0..9

思路:后缀数组

因为前驱与后继的关系已经变化,就不能用下标直接加减

i的后继是唯一的,i的前驱却不一定

所以对于后继使用倍增,对于前驱每个位置暴力开队列存储,需要的时候再拿出来

在判断的地方稍作修改

 #include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 310000
#define MOD 1000000007
#define eps 1e-8
#define pi acos(-1)
queue<int> q[N]; char ch[N];
int n,s[N],sa[N],wa[N],wb[N],wc[N],wd[N],height[N],Rank[N],
f[N][]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} bool cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[f[a][l]]==r[f[b][l]];
// return r[a]==r[b]&&r[a+l]==r[b+l]; 原来的写法
} void getsa(int *r,int *sa,int n,int m)
{
// printf("\n");
int *x=wa,*y=wb,p;
int k=;
for(int i=;i<n;i++) wc[x[i]=r[i]]++;
for(int i=;i<m;i++) wc[i]+=wc[i-];
for(int i=n-;i>=;i--) sa[--wc[x[i]]]=i;
for(int j=,p=;p<n;j*=,m=p)
{
p=;
/*for(i=n-j;i<n;i++) y[p++]=i;
for(i=0;i<n;i++)
if(sa[i]>=j) y[p++]=sa[i]-j;
*/ //默认后继为i+1应该是这个写法 for(int i=;i<n;i++) q[f[i][k]].push(i);
for(int i=;i<n;i++)
while(!q[sa[i]].empty())
{
y[p++]=q[sa[i]].front();
q[sa[i]].pop();
}
for(int i=;i<n;i++) wd[i]=x[y[i]];
for(int i=;i<m;i++) wc[i]=;
for(int i=;i<n;i++) wc[wd[i]]++;
for(int i=;i<m;i++) wc[i]+=wc[i-];
for(int i=n-;i>=;i--) sa[--wc[wd[i]]]=y[i];
swap(x,y);
p=; x[sa[]]=;
for(int i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],k)?p-:p++;
//printf("%d %d %d\n",k,j,p);
k++;
if(j>n) break; //加上这句就A了,应该都是N很大,D[i]相同的数据吧,名次的并列很多
}
} int main()
{
freopen("hdoj6223.in","r",stdin);
freopen("hdoj6223.out","w",stdout);
int cas;
scanf("%d",&cas);
for(int v=;v<=cas;v++)
{
printf("Case #%d: ",v);
scanf("%d",&n);
scanf("%s",ch);
for(int i=;i<n;i++) s[i]=ch[i]-''+;
for(int i=;i<n;i++) f[i][]=(1LL*i*i+)%n; for(int j=;j<=;j++)
for(int i=;i<n;i++) f[i][j]=f[f[i][j-]][j-]; s[n]=;
getsa(s,sa,n+,);
int k=sa[n];
for(int i=;i<=n;i++)
{
printf("%c",ch[k]);
k=f[k][];
}
printf("\n");
for(int i=;i<=max(,n);i++)
{
s[i]=sa[i]=wa[i]=wb[i]=wc[i]=wd[i]=
Rank[i]=;
}
}
return ;
}

【HDOJ6223】Infinite Fraction Path(后缀数组,倍增)的更多相关文章

  1. hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)

    题目传送门 题目大意:给出n座城市,每个城市都有一个0到9的val,城市的编号是从0到n-1,从i位置出发,只能走到(i*i+1)%n这个位置,从任意起点开始,每走一步都会得到一个数字,走n-1步,会 ...

  2. 【bzoj5073】[Lydsy1710月赛]小A的咒语 后缀数组+倍增RMQ+贪心+dp

    题目描述 给出 $A$ 串和 $B$ 串,从 $A$ 串中选出至多 $x$ 个互不重合的段,使得它们按照原顺序拼接后能够得到 $B$ 串.求是否可行.多组数据. $T\le 10$ ,$|A|,|B| ...

  3. 【bzoj3879】SvT 后缀数组+倍增RMQ+单调栈

    题目描述 (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始位置来表示), ...

  4. 2017 ACM/ICPC 沈阳 G题 Infinite Fraction Path

    The ant Welly now dedicates himself to urban infrastructure. He came to the kingdom of numbers and s ...

  5. HDU6223 Infinite Fraction Path bfs+剪枝

    Infinite Fraction Path 这个题第一次看见的时候,题意没搞懂就没做,这第二次也不会呀.. 题意:第i个城市到第(i*i+1)%n个城市,每个城市有个权值,从一个城市出发走N个城市, ...

  6. 2017沈阳区域赛Infinite Fraction Path(BFS + 剪枝)

    Infinite Fraction Path Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java ...

  7. HDU - 6223 Infinite Fraction Path (倍增+后缀数组)

    题意:给定一个长度为n(n<=150000)的字符串,每个下标i与(i*i+1)%n连边,求从任意下标出发走n步能走出的字典序最大的字符串. 把下标看成结点,由于每个结点有唯一的后继,因此形成的 ...

  8. Infinite Fraction Path HDU 6223 2017沈阳区域赛G题题解

    题意:给你一个字符串s,找到满足条件(s[i]的下一个字符是s[(i*i+1)%n])的最大字典序的长度为n的串. 思路:类似后缀数组,每次倍增来对以i开头的字符串排序,复杂度O(nlogn).代码很 ...

  9. 2017 icpc 沈阳 G - Infinite Fraction Path

    题目大意:有n个点, 每个点有一个数字0 - 9, 第 i 个点只能到 第(i * i + 1)个点,问你在哪个点出发走n次构成的数字串最大. 思路:利用求后缀数组的倍增比较思想, 许多细节需要注意. ...

随机推荐

  1. Netbeans使用笔记

    Netbeans 新建项目 A brand new project 选择"文件">"新建项目"以打开新建项目向导. 在向导中,选择 "C/C++ ...

  2. vue cli的安装与使用

    一.简介 vue作为前端开发的热门工具,受到前端开发人员的喜爱.为了简化项目的构建,采用vue cli来简化开发. vue cli是一个全局安装的npm包,提供了终端使用的命令.vue create可 ...

  3. Linux内核漏洞利用-环境配置(转)

    实验环境: Ubuntu-14.04.1 x86 linux-2.6.32.1 busybox-1.27.2 qemu 0x00 安装qemu sudo apt-get install qemu qe ...

  4. 基于Passthru的NDIS开发的个人理解

    这几天对NDIS的学习,基本思路是:首先熟悉理论知识→然后下载一个例子进行研究→最后例子自己模仿扩展→最最后尝试自己写一个新的. Passthru是微软NDIS自己写的一个框架驱动,NDIS开发者可以 ...

  5. Xcode及Mac快捷键

    1. 文件 CMD + N: 新文件CMD + SHIFT + N: 新项目CMD + O: 打开CMD + S: 保存CMD + SHIFT + S: 另存为CMD + W: 关闭窗口CMD + S ...

  6. sscanf的使用

    sscanf的使用 语法 int ssanf(const char *buffer, const char *format,[argument]...); 参数 buffer 存储的数据 format ...

  7. 初涉2-SAT

    2-SAT:有趣的图论模型 什么是2-SAT SAT是适定性(Satisfiability)问题的简称.之所以研究2-sat是因为当k>2时,k-sat问题已经被证明是NPC的了. 2-sat问 ...

  8. (10)zabbix item key详解

    1. 灵活的参数 参数位置可用接收任意参数则是灵活的.例如vfs.fs.size[*],”*”星号可以使用任意的参数,例如:vfs.fs.size[/]vfs.fs.size[/opt] 2. Key ...

  9. 一篇关于BEM命名规范

    一直以来自己对命名都是比较混乱的,并没有一个比较好的格式来命名,最近自己碰巧学习到了BEM命名规范,我想谈谈自己的理解以供自己来学习,同时也可以和各位大佬一起学习. BEM是一个很有用的方法可以创建复 ...

  10. 使用selenium和phantomJS浏览器获取网页内容的小演示

    # 使用selenium和phantomJS浏览器获取网页内容的小演示 # 导入包 from selenium import webdriver # 使用selenium库里的webdriver方法调 ...