bzoj2806: [Ctsc2012]Cheat(SAM+DP)
2806: [Ctsc2012]Cheat
题目:传送门
题解:
感觉这题考的更多的就是DP啊...
看完题目的第一反应就是广义SAM...(然而并不会)
再YY一会儿想起来可以直接将作文库连成一个母串(中间用2隔开)去跑SAM,然后直接把文章当成是子串在自动机上面跑(字符串匹配问题的套路啊)
考虑DP:设f[i]表示前i个位置的最大匹配长度。那么f[i]=max(f[i],f[j]+i-j);
直接DP肯定爆炸,再考虑利用SAM来预处理一个match[],match[i]表示当前文章以第i个位置结尾的子串和作文库匹配的最长长度(直接在自动机里面乱跑)
L满足而分性,直接二分,然后我们会发现对于f[i]有影响的其实只在于[i-match[i],i-L],i-L这个玩意肯定单调递增啊...
一波单调队列直接搞:对于队头,如果位置在合法区间内,则直接可以找到最优解来更新f[i]
槽点:一开始被卡精度...%AC_Artist.zig_zag之后又WA了...然后发现自己脑残在check里memset。。。(做了一上午...菜啊),数据真的有点水
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
struct SAM
{
int son[],fail,dep;
SAM(){memset(son,,sizeof(son));fail=dep=;}
}ch[];int a[],match[],root,cnt,last;
int n,m;
char s[],st[];
void add(int k)
{
int x=a[k];
int p=last,np=++cnt;ch[np].dep=ch[p].dep+;
while(p && ch[p].son[x]==)ch[p].son[x]=np,p=ch[p].fail;
if(p==)ch[np].fail=root;
else
{
int q=ch[p].son[x];
if(ch[q].dep==ch[p].dep+)ch[np].fail=q;
else
{
int nq=++cnt;ch[nq]=ch[q];
ch[nq].dep=ch[p].dep+;
ch[np].fail=ch[q].fail=nq;
while(p && ch[p].son[x]==q)ch[p].son[x]=nq,p=ch[p].fail;
}
}
last=np;
}
void get_match(int len)
{
int p=root,sum=;
for(int i=;i<=len;i++)
{
int x=s[i]-'';
if(ch[p].son[x]!=)sum++,p=ch[p].son[x];
else //失配了就跳fail
{
while(p && ch[p].son[x]==)p=ch[p].fail;
if(p==)p=root,sum=;
else sum=ch[p].dep+,p=ch[p].son[x];
}
match[i]=sum;
}
}
int f[],list[];
bool check(int L,int len)
{
//if(L==0)return true;
f[]=;list[]=;
int p,head=,tail=;
for(int i=;i<=len;i++)
{
f[i]=f[i-];p=i-L;if(p<)continue;
while(head<=tail && f[p]+i-p>f[list[tail]]+i-list[tail])tail--;list[++tail]=p;
while(head<=tail && list[head]<i-match[i])head++;
if(head<=tail)f[i]=max(f[i],f[list[head]]+i-list[head]);
}
double anss=double(f[len])/double(len);
return anss>=0.8999999999;
}
int main()
{
scanf("%d%d",&n,&m);int la=;
cnt=;root=last=++cnt;
for(int i=;i<=m;i++)
{
scanf("%s",st+);int len=strlen(st+);int k=;
for(int j=la;j<=len+la-;j++)
{
k++;a[j]=st[k]-'';
add(j);
}
if(i!=m){la=len+la;a[la]=;add(la);la++;}
}
while(n--)
{
scanf("%s",s+);int len=strlen(s+);
get_match(len);
int l=,r=len,ans=;
while(l<=r)
{
int mid=(l+r)/;
if(check(mid,len))ans=mid,l=mid+;
else r=mid-;
}
printf("%d\n",ans);
}
return ;
}
bzoj2806: [Ctsc2012]Cheat(SAM+DP)的更多相关文章
- [bzoj2806][Ctsc2012]Cheat(后缀自动机(SAM)+二分答案+单调队列优化dp)
偷懒直接把bzoj的网页内容ctrlcv过来了 2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1943 ...
- BZOJ2806:[CTSC2012]Cheat(广义SAM,二分,DP)
Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 Output N行,每行一 ...
- BZOJ2806 [Ctsc2012]Cheat 【后缀自动机 + 二分 + 单调队列优化DP】
题目 输入格式 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库 的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 输出格式 N行,每行一个整数,表示这篇作文的 ...
- BZOJ2806: [Ctsc2012]Cheat(广义后缀自动机,单调队列优化Dp)
Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数接下来M行的01串,表示标准作文库接下来N行的01串,表示N篇作文 Output N行,每行一个整 ...
- bzoj2806 [Ctsc2012]Cheat
我们的目的就是找到一个最大的L0,使得该串的90%可以被分成若干长度>L0的字典串中的子串. 明显可以二分答案,对于二分的每个mid 我们考虑dp:f[i]表示前i个字符,最多能匹配上多少个字符 ...
- 【BZOJ2806】[Ctsc2012]Cheat 广义后缀自动机+二分+单调队列优化DP
[BZOJ2806][Ctsc2012]Cheat Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数接下来M行的01串,表示标准作文库接下来N行的 ...
- 【BZOJ 2806】 2806: [Ctsc2012]Cheat (SAM+二分+DP+单调队列)
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1262 Solved: 643 Description ...
- bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 583 Solved: 330[Submit][Statu ...
- BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]
2806: [Ctsc2012]Cheat 题意: 多个主串和多个询问串,每次询问将询问串分成多个连续子串,如果一个子串长度>=L且在主串中出现过就是熟悉的 如果熟悉的字符串长度>=询问串 ...
随机推荐
- 用户注册登录验证 多版本集合 + hashlib加密
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2018/5/6 0006 12:22# @Author : Anthony.Waa# @S ...
- CI中的文件上传
//首先在控制器中装载url类和view视图: //在view视图中创建一个表单,注:在做文件上传一定要写encype=“multipart/form-data”: //form表单的提交页面应该使用 ...
- INFORMIX MATCHES的使用详解
MATCHES 运算符返回 TRUE ,如果一个字符串与给定的掩码匹配. 语法 expr [NOT] MATCHES mask [ ESCAPE "char" ] ex ...
- es6学习 http://es6.ruanyifeng.com/
基础学习 http://es6.ruanyifeng.com/ 够了 1字符串 字符串的遍历器接口 for (let codePoint of 'foo') { console.log(code ...
- go开发和运行环境的配置
1.运行环境的下载.安装.配置: 下载:http://www.golangtc.com/download 官网下载经常被墙屏蔽,所以就从golang中国下载; 安装及其配置:http://jingy ...
- Qwt--散点图/函数图
1.Qwt库 QwtPlot是用来绘制二维图像的widget.在它的画板上可以无限制的显示绘画组件.绘画组件可以是曲线(QwtPlotCurve).标记(QwtPlotMarker).网格(QwtPl ...
- 0xc000007b:vs2012+Opencv2.4.4出现"0xc000007b"问题
在64位系统中,VS2012+opencv2.4.4下编程出现一个问题,我简单的读取图片就出现"应用程序无法正常启动0xc000007b"的问题:如图: 注意事项:把运行环境改成 ...
- hust 1570 Lazy. Lazy. Laaaaaaaaaaaazy!
链接 1570 - Lazy. Lazy. Laaaaaaaaaaaazy! 题意 给出三种按键,caplock,shift,nomal(像正常键盘操作一样) ,输入三串字符串,s1,s2,txt, ...
- 实现路由器自动登录校园网(edu)
准备工作: (1)一个可以刷openwrt固件的路由器,如大多人使用的crazybox版本的路由. (2)一个可用的edu账号. (3)一个浏览器(firfox,chrome) 下面开始: 一:刷op ...
- net--技术栈(大图)