【SPOJ687&POJ3693】Maximum repetition substring(后缀数组)
题意:
n<=1e5
思路:
From http://hzwer.com/6152.html
往后匹配多远 r 用ST表求lcp即可。。。往前 l 就把串反过来再做一下。。
但是有可能求出来的最长串可以前移/后移几位
即开头可以在落在[i−l,i−l+(l+r)mod L]
区间内字典序最小的还要用ST表找rank区间最值
有空需要学习一下结构体写法 一模一样的东西写多次太累了
- #include<cstdio>
- #include<cstring>
- #include<string>
- #include<cmath>
- #include<iostream>
- #include<algorithm>
- #include<map>
- #include<set>
- #include<queue>
- #include<vector>
- 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 110000
- #define MOD 1000000007
- #define eps 1e-8
- #define pi acos(-1)
- #define oo 1000000000
- char ch[N];
- int n,i,s[N],sa[N],wa[N],wb[N],wc[N],wd[N],height[N],rank[N],
- ans,mx,ansl,ansr,f[][N][],g[][N],save[N],Log[N],bin[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[a+l]==r[b+l];
- }
- void getsa(int *r,int *sa,int n,int m)
- {
- int *x=wa,*y=wb,j,p;
- for(i=;i<n;i++) wc[x[i]=r[i]]++;
- for(i=;i<m;i++) wc[i]+=wc[i-];
- for(i=n-;i>=;i--) sa[--wc[x[i]]]=i;
- for(j=,p=;p<n;j*=,m=p)
- {
- p=;
- for(i=n-j;i<n;i++) y[p++]=i;
- for(i=;i<n;i++)
- if(sa[i]>=j) y[p++]=sa[i]-j;
- for(i=;i<n;i++) wd[i]=x[y[i]];
- for(i=;i<m;i++) wc[i]=;
- for(i=;i<n;i++) wc[wd[i]]++;
- for(i=;i<m;i++) wc[i]+=wc[i-];
- for(i=n-;i>=;i--) sa[--wc[wd[i]]]=y[i];
- swap(x,y);
- p=; x[sa[]]=;
- for(i=;i<n;i++) x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
- }
- }
- void getheight(int *r,int *sa,int n)
- {
- int i,j,k=;
- for(i=;i<=n;i++) rank[sa[i]]=i;
- for(i=;i<n;height[rank[i++]]=k)
- {
- if(k) k--;
- j=sa[rank[i]-];
- while(r[i+k]==r[j+k]) k++;
- }
- }
- void init()
- {
- memset(s,,sizeof(s));
- memset(sa,,sizeof(sa));
- memset(wa,,sizeof(wa));
- memset(wb,,sizeof(wb));
- memset(wc,,sizeof(wc));
- memset(wd,,sizeof(wd));
- memset(height,,sizeof(height));
- memset(rank,,sizeof(rank));
- }
- int lcp(int p,int x,int y)
- {
- int t;
- int L=g[p][x];
- int R=g[p][y];
- if(L>R){t=L; L=R; R=t;}
- L++;
- int q=Log[R-L+];
- return min(f[p][L][q],f[p][R-bin[q]+][q]);
- }
- int query(int x,int y)
- {
- int q=Log[y-x+];
- return min(f[][x][q],f[][y-bin[q]+][q]);
- }
- void solve(int L)
- {
- for(int i=;i+L<n;i+=L)
- if(ch[i]==ch[i+L])
- {
- int r=lcp(,i,i+L);
- // printf("1 %d %d %d\n",i,i+L,r);
- int l=lcp(,n-i,n-i-L);
- // printf("2 %d %d %d\n",n-i,n-i-L,l);
- if((l+r)/L+>mx) {mx=(l+r)/L+; ans=oo;}
- if((l+r)/L+==mx)
- {
- int t=query(i-l,i-l+(l+r)%L);
- // printf("%d %d %d\n",i-l,i-l+(l+r)%L,t);
- if(t<ans)
- {
- ans=t;
- ansl=save[t];
- ansr=ansl+mx*L-;
- }
- }
- }
- }
- int main()
- {
- //freopen("poj3693.in","r",stdin);
- //freopen("poj3693.out","w",stdout);
- bin[]=;
- for(int i=;i<;i++) bin[i]=bin[i-]<<;
- Log[]=-;
- for(int i=;i<=;i++) Log[i]=Log[i/]+;
- int cas=;
- while(scanf("%s",ch))
- {
- if(ch[]=='#') break;
- cas++;
- printf("Case %d: ",cas);
- init();
- n=strlen(ch);
- for(int i=;i<n;i++) s[i]=ch[i]-'a'+;
- s[n]=;
- getsa(s,sa,n+,);
- getheight(s,sa,n);
- for(int i=;i<n;i++) f[][i][]=rank[i];
- int len=Log[n];
- for(int i=;i<=n;i++) f[][i][]=height[i];
- for(int i=;i<=len;i++)
- for(int j=;j+bin[i]-<=n;j++)
- f[][j][i]=min(f[][j][i-],f[][j+bin[i-]][i-]);
- for(int i=;i<=n;i++) g[][i]=rank[i];
- for(int i=;i<=n;i++) save[i]=sa[i];
- init();
- for(int i=;i<n;i++) s[i]=ch[n--i]-'a'+;
- s[n]=;
- getsa(s,sa,n+,);
- getheight(s,sa,n);
- for(int i=;i<=n;i++) f[][i][]=height[i];
- for(int i=;i<=len;i++)
- for(int j=;j+bin[i]-<=n;j++)
- f[][j][i]=min(f[][j][i-],f[][j+bin[i-]][i-]);
- for(int i=;i<=n;i++) g[][i]=rank[i];
- for(int i=;i<=len;i++)
- for(int j=;j+bin[i]-<=n-;j++)
- f[][j][i]=min(f[][j][i-],f[][j+bin[i-]][i-]);
- ansl=ansr=;
- mx=; ans=oo;
- for(int i=;i<n;i++)
- if(ch[i]<ch[ansl]){ans=; ansl=ansr=i;}
- for(int i=;i<=n;i++) solve(i);
- for(int i=ansl;i<=ansr;i++) printf("%c",ch[i]);
- printf("\n");
- }
- return ;
- }
【SPOJ687&POJ3693】Maximum repetition substring(后缀数组)的更多相关文章
- POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS Memory Li ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- POJ3693 Maximum repetition substring 后缀数组
POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...
- poj3693 Maximum repetition substring (后缀数组+rmq)
Description The repetition number of a string is defined as the maximum number R such that the strin ...
- Maximum repetition substring 后缀数组
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7578 Acc ...
- POJ 3693 Maximum repetition substring ——后缀数组
重复次数最多的字串,我们可以枚举循环节的长度. 然后正反两次LCP,然后发现如果长度%L有剩余的情况时,答案是在一个区间内的. 所以需要找到区间内最小的rk值. 两个后缀数组,四个ST表,$\Thet ...
- 【Poj-3693】Maximum repetition substring 后缀数组 连续重复子串
POJ - 3693 题意 SPOJ - REPEATS的进阶版,在这题的基础上输出字典序最小的重复字串. 思路 跟上题一样,先求出最长的重复次数,在求的过程中顺便纪录最多次数可能的长度. 因为sa数 ...
- poj 3693 Maximum repetition substring (后缀数组)
其实是论文题.. 题意:求一个字符串中,能由单位串repeat得到的子串中,单位串重复次数最多的子串.若有多个重复次数相同的,输出字典序最小的那个. 解题思路:其实跟论文差不多,我看了很久没看懂,后来 ...
- POJ 3693 Maximum repetition substring (后缀数组+RMQ)
题意:给定一个字符串,求其中一个由循环子串构成且循环次数最多的一个子串,有多个就输出最小字典序的. 析:枚举循环串的长度ll,然后如果它出现了两次,那么它一定会覆盖s[0],s[ll],s[ll*2] ...
- poj3693 Maximum repetition substring
题意 给出一个长度为\(n(n\leqslant 100000)\)的串,求一个字典序最小的子串使得它是某个字符串重复\(k\)次得到的,且\(k\)最大 题解 后缀数组论文上的题,跟上一篇uva那个 ...
随机推荐
- GNU make(2)
GNU make(2) 参考: GNU Make学习总结(二) 变量 变量由一个前导符号$加上字符或者是括号字符组成, 名称区分大小写. 命名: 习惯上用全部大写字符表示常量, 小写字符表示变量, 单 ...
- fluent_python1
Magic Method python中有些跟对象本身有关的方法, 以两个下划线开始,两个下划线结束, 一般称为魔法方法(magic method). 比如 obj[key] 的背后就是 __geti ...
- Gym - 101291C (很有意思的最短路)
题意: 给出一张地图和机器人还有出口的位置,地图上面有障碍.然后给出UDLR上下左右四种指令,遇到障碍物或者越界的指令会忽略,剩下的继续执行. 只要到达出口就算找到出口,然后给你一串指令,让你修改指令 ...
- (三)VMware harbor使用http访问
参考:https://www.cnblogs.com/biglittleant/p/7283738.html harbor使用http访问 如果使用http启动harbor需要在docker中配置-- ...
- CPP-基础:wchar_t
目 录 1简介 2例如 3将char转换成wchar_t 1.简介 wchar_t是C/C++的字符数据类型,是一种扩展的字符存储方式,wchar_t类型主要用在国际化程序的实现中,但它不等同于uni ...
- 【转】Python 访问 HDFS
1.前言 hdfs , Hadoop Distributed File System.Hadoop的分布式文件系统,安全行和扩展性没得说. 访问HDFS的方式有以下几种: 命令行方式:FS Shell ...
- WebStorm换主题(护眼)
一.下载喜欢颜色的主题 http://www.phpstorm-themes.com/ 我用的豆沙绿护眼 <scheme name="Solarized Light My" ...
- 数据库事务ACID和事务的隔离级别
借鉴:https://blog.csdn.net/zh521zh/article/details/69400053和https://blog.csdn.net/May_3/article/detail ...
- (2)zabbix硬件需求
1. 硬件需求 无非就是cpu.内存.硬盘之类的1.1 CPU由你的zabbix数据库使用情况来做决定,如果你监控的项目越多,那你的cpu要越好.具体多好,下面有个表格 1.2 内存与硬盘最基本的需求 ...
- linux各种终端类型的区别和概念
1 pty(虚拟终端或伪终端): 当我们远程telnet到主机或使用xterm时不也需要一个终端交互么?是的,这就是虚拟终端pty(pseudo-tty). 2 tty(终端设备的统称):tty一词源 ...