【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 ...
随机推荐
- tar -h 参数
1.1.1 tar命令参数-h,-h参数会把软链接指向的文件也打包. [root@ob2 mytmp]# ll total 8 -rw-r--r--. 1 root root 910 Aug 12 2 ...
- MongoDB Shell 了解使用
配置环境变量 WIN10系统:右键单击"此电脑"--属性--高级系统设置--高级--环境变量,添加C:\Program Files\MongoDB\Server\3.0\bin 如 ...
- Golang map 如何进行删除操作?
Cyeam 关注 2017.11.02 10:02* 字数 372 阅读 2784评论 0喜欢 3 map 的删除操作 Golang 内置了哈希表,总体上是使用哈希链表实现的,如果出现哈希冲突,就把冲 ...
- Nutch系列1:简介
由Java实现的,开放源代码(open-source)的web搜索引擎. Nutch 致力于让每个人都能很容易, 同时花费很少就可以配置世界一流的Web搜索引擎. 为了完成这一宏伟的目标, Nutch ...
- 【转】苹果App Store新规:6月1日后所有应用必须支持IPv6-only网络
在WWDC2015上苹果宣布iOS9将支持纯IPv6的网络服务.2016年初开始所有提交到App Store的应用必须支持IPv6.为确保现有的应用是兼容的,我们需要注意下面几点. 不建议使用底层的网 ...
- 关于在Android中访问和使用到上下文变量
在监听器内部实现类中要引用上下文变量this的时候 一.采用类名.this的方法 FActivity.this 二.采用全局变量当做中间变量 1.先定义一个全局变量 private Context m ...
- FFmpeg在Android上的移植优化步骤
http://blog.csdn.net/feixiang_john/article/details/7894188 从事多媒体软件开发的人几乎没有不知道FFmpeg的,很多视频播放器都是基于FFmp ...
- javascript -- js正则表达式
正则表达式可以: 1.测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证 2.替换文本.可以在文档中使用一个正则 ...
- linux -- Ubuntuserver图形界面下安装、配置lampp、phpmyadmin
PHP开发和服务器运行环境首选LAMP组合,即Linux+Apache+Mysql+Php/Perl/Python,能最优化服务器性能.如何在本地电脑Ubuntu 中安装和配置LAMP环境搭建?Ubu ...
- 结构型模式概述(Structural Pattern)
结构型模式可以描述两种不同的东西:类与类的实例.结构型模式可以分为类结构型模式和对象结构型模式. 类结构型模式关心类的组合,可以由多个类组合成一个更大的系统,在类结构型模式中只存在继承关系和实现关系: ...