【BZOJ4698】Sdoi2008 Sandy的卡片 后缀数组+RMQ
【BZOJ4698】Sdoi2008 Sandy的卡片
Description
Input
Output
Sample Input
2 1 2
3 4 5 9
Sample Output
题解:本题让我们求的是变化趋势相同的子串,那么我们直接求出每个数串相邻两项的差,然后用这个差来求最长公共子串就行了。当然,这些差可能会有负值,那就集体减去最小值-1(防止出现0)就行了。先把这些串全部连接起来,中间用极大值隔开,求出sa和height。然后再height数组上维护这样一个区间,使得这个区间中的后缀在每个数串中都出现过,并且区间长度尽可能短,然后从左向右平移这个区间,用RMQ维护区间中最小的height,答案就是这个最大的最小值+1。当然这题也可以二分答案来做。
因为RMQ写错竟然调了一天,感觉我有几年没写RMQ了。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=200010;
int minn,maxx;
int r[maxn],ra[maxn],rb[maxn],st[maxn],sa[maxn],rank[maxn],h[maxn];
int N,M[maxn],sm[maxn],bel[maxn],n,m,v[maxn];
int s[maxn],sum,ans;
int dp[maxn][20],Log[maxn];
void work()
{
int i,j,k,*x=ra,*y=rb,p;
for(i=0;i<n;i++) st[x[i]=r[i]]++;
for(i=1;i<m;i++) st[i]+=st[i-1];
for(i=n-1;i>=0;i--) sa[--st[x[i]]]=i;
for(j=p=1;p<n;j<<=1,m=p)
{
for(i=n-j,p=0;i<n;i++) y[p++]=i;
for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=0;i<m;i++) st[i]=0;
for(i=0;i<n;i++) st[x[y[i]]]++;
for(i=1;i<m;i++) st[i]+=st[i-1];
for(i=n-1;i>=0;i--) sa[--st[x[y[i]]]]=y[i];
for(swap(x,y),i=p=1,x[sa[0]]=0;i<n;i++)
x[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j])?p-1:p++;
}
for(i=1;i<n;i++) rank[sa[i]]=i;
for(i=k=0;i<n-1;h[rank[i++]]=k)
for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
}
void rmq()
{
int i,j;
for(i=2;i<n;i++) Log[i]=Log[i>>1]+1;
for(i=1;i<n;i++) dp[i][0]=h[i];
for(j=1;(1<<j)<n;j++)
for(i=1;i+(1<<j)-1<n;i++)
dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
}
int getmin(int a,int b)
{
int k=Log[b-a+1];
return min(dp[a][k],dp[b-(1<<k)+1][k]);
}
int main()
{
scanf("%d",&N);
int i,j,now=0;
sm[0]=-1;
for(i=1;i<=N;i++)
{
scanf("%d",&M[i]);
sm[i]=sm[i-1]+M[i];
scanf("%d",&v[1]);
for(j=2;j<=M[i];j++)
{
bel[now]=i;
scanf("%d",&v[j]);
r[now]=v[j]-v[j-1];
maxx=max(maxx,r[now]);
minn=min(minn,r[now++]);
}
now++;
}
for(i=0;i<sm[N];i++) r[i]-=minn-1;
r[sm[N]]=0;
m=maxx-minn+1;
for(i=1;i<N;i++) r[sm[i]]=m+1;
n=sm[N]+1,m+=2;
work();
rmq();
for(i=1;i<n;i++)
{
if(!s[bel[sa[i]]])
{
if(sum==N-1) break;
sum++;
}
s[bel[sa[i]]]++;
}
now=1;
for(;i<n;i++)
{
if(!bel[sa[i]]) break;
s[bel[sa[i]]]++;
while(s[bel[sa[now]]]>1) s[bel[sa[now++]]]--;
ans=max(ans,getmin(now+1,i));
}
printf("%d",ans+1);
return 0;
}
【BZOJ4698】Sdoi2008 Sandy的卡片 后缀数组+RMQ的更多相关文章
- BZOJ 4698: Sdoi2008 Sandy的卡片 后缀数组 + RMQ + 查分
题目描述 Sandy和Sue的热衷于收集干脆面中的卡片. 然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型. 每一张卡片都由一些数字进行标记,第i张卡片的 ...
- BZOJ4698: Sdoi2008 Sandy的卡片(后缀数组 二分)
题意 题目链接 Sol 不要问我为什么发两篇blog,就是为了骗访问量 后缀数组的也比较好想,先把所有位置差分,然后在height数组中二分就行了 数据好水啊 // luogu-judger-enab ...
- 【BZOJ-4698】Sandy的卡片 后缀数组
4698: Sdoi2008 Sandy的卡片 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 140 Solved: 55[Submit][Stat ...
- 【bzoj4698】[Sdoi2008] Sandy的卡片 后缀数组
题目描述 Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型.每一张卡片都由一些数字进行标记,第i张卡片的序列 ...
- SDOI2008 Sandy的卡片( 后缀数组 )
求出后缀数组, 然后二分答案, 对height数组分组检验答案. 时间复杂度O(|S| log|S|) ------------------------------------------------ ...
- BZOJ 4698: Sdoi2008 Sandy的卡片(后缀数组+差分+二分答案)
传送门 解题思路 看到一个子串加一个数字到另一个子串,自然可以想到差分.然后要把所有串都拼起来,求出\(height\)数组后可以二分答案来做,每次二分一个答案后统计一下连续的\(height> ...
- [BZOJ4698][SDOI2008]Sandy的卡片(后缀自动机)
差分之后就是求多串LCS. 对其中一个串建SAM,然后把其它串放在上面跑. 对SAM上的每个状态都用f[x]记录这个状态与当前串的最长匹配长度,res[x]是对每次的f[x]取最小值.答案就是res[ ...
- 洛谷P2463 [SDOI2008]Sandy的卡片(后缀数组SA + 差分 + 二分答案)
题目链接:https://www.luogu.org/problem/P2463 [题意] 求出N个串中都出现的相同子串的最长长度,相同子串的定义如题:所有元素加上一个数变成另一个,则这两个串相同,可 ...
- BZOJ 4698: Sdoi2008 Sandy的卡片 [后缀自动机]
4698: Sdoi2008 Sandy的卡片 题意:差分后就是多个串LCS SAM+map大法好 模板打错 智力-2 #include <iostream> #include <c ...
随机推荐
- iOS彩票项目--第五天,新特性引导页的封装、返回按钮的自定义、导航控制器的滑动返回以及自定义滑动返回功能
一.上次实现了在AppDelegate中通过判断app版本决定是否进入新特性页面,今天将AppDelegate中的一坨进行了封装.将self.window的根控制器到底应该为新特性界面,还是主页面,封 ...
- JSON教程
一.什么是JSON 1.JSON指的是JavaScript对象表示法(JavaScript Object Notation). 2.JSON是轻量级的文本数据交换格式,比XML更小.更快.更易解析. ...
- Laravel Debugbar
Installation Require this package with composer: composer require barryvdh/laravel-debugbar After up ...
- jquery easyui datagrid 分页实现
通常情况下页面数据的分页显示分成真假两种.真分页是依靠后台查询时控制调出数据的数量来实现分页,也就是说页面在后台对数据进行处理,仅传输当前需要页的数据到前台来显示.而假分页则是后台一次性将所有的数据一 ...
- C++很“虚”
0引言:在学习C++时,碰到过以下四个以“虚”命名的概念,在系统理解这些高大上的术语后,才发现它们果真“名不虚传”. 为了方便捋清楚这些概念和之间的相互关系,本人对其进行了系统的总结,欢迎讨论. 1. ...
- (转)学习linux的几本书
成为一名精通 Linux 程序设计的高级程序员一直是不少朋友孜孜以求的目标.根据中华英才网统计数据,北京地区 Linux 程序员月薪平均为 Windows 程序员的 1.8 倍.Java 程序员的 2 ...
- HTC Desire 816刷机教程(图文)
HTC Desire 816刷机教程也来了,今天在这里主要是来说说如何刷机的,这个刷机是采用卡刷的方式,也就是利用第三方的recovery来刷入第三方的zip包,因为第三方的zip包都是支持卡刷的,很 ...
- nginx+tomcat实现负载均衡以及session共享(linux centos7环境)
一.nginx的安装 1.准备三份tomcat tomcat1 设置端口 8080 tomcat2 设置端口 8081 tomcat3 设置端口 8082 2. 下载nginx 3. 解压到/home ...
- MyEclipse 对项目进行build path无效
今天发现昨天从svn下载下来的项目在MyEclipse中无法build path .提示no actions available 在网上找了下,是由于.projects文件的问题,须要在当中的natu ...
- 【Graphlab】
https://dato.com/ graphlab