字符串[未AC](后缀自动机):HEOI 2016 str



超级恶心,先后用set维护right,再用主席树维护,全部超时,本地测是AC的。放心,BZOJ上还是1S限制,貌似只有常数优化到一定境界的人才能AC吧。
总之我是精神胜利了哦耶QAQ
#include <iostream>
#include <cstring>
#include <cstdio>
#define lb lower_bound
#define ub upper_bound
#include <set>
using namespace std;
const int N=;
int fa[N][],ch[N][],len[N],pos[N];
int lst,cnt;set<int>t[N];
int n,Q,a,b,c,d;char s[N];
void Init(){lst=cnt=;}
void Insert(int c){
int p=lst,np=lst=++cnt;len[np]=len[p]+;
while(p&&ch[p][c]==)ch[p][c]=np,p=fa[p][];
if(!p)fa[np][]=;
else{
int q=ch[p][c],nq;
if(len[q]==len[p]+)fa[np][]=q;
else{
len[nq=++cnt]=len[p]+;
fa[nq][]=fa[q][];fa[q][]=fa[np][]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
while(ch[p][c]==q)ch[p][c]=nq,p=fa[p][];
}
}
}
int cntE,fir[N],to[N],nxt[N];
void addedge(int a,int b){
nxt[++cntE]=fir[a];
to[fir[a]=cntE]=b;
} set<int>Merge(set<int>x,set<int>y){
if(x.size()<y.size())swap(x,y);
x.insert(y.begin(),y.end());
//delete &y;
return x;
} void DFS(int x){
for(int i=fir[x];i;i=nxt[i])
DFS(to[i]),t[x]=Merge(t[x],t[to[i]]);
} bool Judge(int p,int l,int r){
return t[p].lb(l)!=t[p].ub(r);
} int Find(int x,int l){
for(int i=;i>=;i--)
if(fa[x][i]&&len[fa[x][i]]>=l)
x=fa[x][i];
return x;
} int Solve(){
int l=,r=min(d-c,b-a)+;
while(l<=r){
int mid=(l+r)>>;
int p=Find(pos[c],mid);
if(Judge(p,a,b-mid+))l=mid+;
else r=mid-;
}
return r;
} int main(){
freopen("heoi2016_str5.in","r",stdin);
freopen("heoi2016_str.out","w",stdout);
Init();scanf("%d%d%s",&n,&Q,s+);
for(int i=n;i>=;i--){Insert(s[i]-'a');t[pos[i]=lst].insert(i);}
for(int i=;i<=cnt;i++)addedge(fa[i][],i);DFS();
for(int k=;k<=;k++)
for(int i=;i<=cnt;i++)
fa[i][k]=fa[fa[i][k-]][k-];
while(Q --){
scanf("%d%d%d%d",&a,&b,&c,&d);
printf("%d\n",Solve());
}
return ;
}
然后是应该AC的:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <ctime>
using namespace std;
const int N=;
int fa[N][],ch[N][],len[N],pos[N];
int lst,cnt,n,Q;char s[N];
void Init(){lst=cnt=;}
void Insert(int c){
int p=lst,np=lst=++cnt;len[np]=len[p]+;
while(p&&ch[p][c]==)ch[p][c]=np,p=fa[p][];
if(!p)fa[np][]=;
else{
int q=ch[p][c],nq;
if(len[q]==len[p]+)fa[np][]=q;
else{
len[nq=++cnt]=len[p]+;
fa[nq][]=fa[q][];fa[q][]=fa[np][]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
while(ch[p][c]==q)ch[p][c]=nq,p=fa[p][];
}
}
}
int cntE,fir[N],to[N],nxt[N];
void addedge(int a,int b){
nxt[++cntE]=fir[a];
to[fir[a]=cntE]=b;
} int id[N],ed[N],tot;
int rt[N],sum[N*],son[N*][];
void Insert(int pre,int &rt,int l,int r,int g){
sum[rt=++tot]=sum[pre]+;
son[rt][]=son[pre][];
son[rt][]=son[pre][];
if(l==r)return;int mid=l+r>>;
if(mid>=g)Insert(son[pre][],son[rt][],l,mid,g);
else Insert(son[pre][],son[rt][],mid+,r,g);
}
int Query(int x,int l,int r,int a,int b){
if(l>=a&&r<=b||!sum[x])return sum[x];
int ret=,mid=l+r>>;
if(mid>=a)ret=Query(son[x][],l,mid,a,b);
if(mid<b)ret+=Query(son[x][],mid+,r,a,b);
return ret;
} bool Judge(int p,int l,int r){
int A=Query(rt[l-],,cnt,id[p],ed[p]);
int B=Query(rt[r],,cnt,id[p],ed[p]);
return A<B;
} int st[N],top;
int main(){
freopen("heoi2016_str.in","r",stdin);
freopen("heoi2016_str.out","w",stdout);
Init();scanf("%d%d%s",&n,&Q,s+);
for(int i=n;i>=;i--)Insert(s[i]-'a'),pos[i]=lst;
for(int i=;i<=cnt;i++)addedge(fa[i][],i);
for(int k=;k<=;k++)for(int i=;i<=cnt;i++)
fa[i][k]=fa[fa[i][k-]][k-];
st[top=]=;
while(top){
int x=st[top];
if(id[x]){ed[x]=tot;top--;}
else{
id[x]=++tot;
for(int i=fir[x];i;i=nxt[i])
st[++top]=to[i];
}
} tot=;
for(int i=;i<=n;i++)
Insert(rt[i-],rt[i],,cnt,id[pos[i]]);
int a,b,c,d;
while(Q --){
scanf("%d%d%d%d",&a,&b,&c,&d);
int l=,r=min(d-c,b-a)+;
while(l<=r){
int mid=l+r>>,p=pos[c];
for(int i=;i>=;i--)
if(fa[p][i]&&len[fa[p][i]]>=mid)
p=fa[p][i];
if(Judge(p,a,b-mid+))l=mid+;
else r=mid-;
}
printf("%d\n",r);
}
//printf("%lf\n", (double)clock()/CLOCKS_PER_SEC);
return ;
}
有毒啊,后缀数组都写挂了,TLE。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=;
int n,Q,r[N],Wa[N],Wb[N],Wv[N],Ws[N];
int rk[N],sa[N],lcp[N],mm[N],Min[N][];
int len,cnt,ch[N*][],sum[N*],rt[N];
char s[N];
bool cmp(int *p,int i,int j,int l){
return p[i]==p[j]&&p[i+l]==p[j+l];
} void DA(int n,int m){
int i,j,p,*x=Wa,*y=Wb;
for(i=;i<m;i++)Ws[i]=;
for(i=;i<n;i++)++Ws[x[i]=r[i]];
for(i=;i<m;i++)Ws[i]+=Ws[i-];
for(i=n-;i>=;i--)sa[--Ws[x[i]]]=i; for(p=,j=;p<n;m=p,j<<=){
for(p=,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<m;i++)Ws[i]=;
for(i=;i<n;i++)++Ws[Wv[i]=x[y[i]]];
for(i=;i<m;i++)Ws[i]+=Ws[i-];
for(i=n-;i>=;i--)sa[--Ws[Wv[i]]]=y[i];
for(swap(x,y),x[sa[]]=,i=,p=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
} void LCP(int n){
int i,j,k=;
for(i=;i<=n;i++)rk[sa[i]]=i;
for(i=;i<n;lcp[rk[i++]]=k)
for(k-=k>,j=sa[rk[i]-];r[i+k]==r[j+k];k++);
} #define mid ((l+r)>>1)
void Insert(int pre,int &rt,int l,int r,int g,int d){
sum[rt=++cnt]=sum[pre]+d;ch[rt][]=ch[pre][];
ch[rt][]=ch[pre][];if(l==r)return;
if(mid>=g)Insert(ch[pre][],ch[rt][],l,mid,g,d);
else Insert(ch[pre][],ch[rt][],mid+,r,g,d);
} int Query(int pre,int rt,int l,int r,int a,int b){
if(l>=a&&r<=b)return sum[rt]-sum[pre];int ret=;
if(mid>=a)ret=Query(ch[pre][],ch[rt][],l,mid,a,b);
if(mid<b)ret+=Query(ch[pre][],ch[rt][],mid+,r,a,b);
return ret;
} void Prepare(int n){
mm[]=-;
for(int i=;i<=n;i++){
mm[i]=mm[i-];
if(!(i&i-))mm[i]+=;
Min[i][]=lcp[i];
}
for(int k=;k<=mm[n];k++)
for(int i=;i+(<<k-)<=n;i++)
Min[i][k]=min(Min[i][k-],Min[i+(<<k-)][k-]);
} int Qmin(int x,int y){
if(x>y)swap(x,y);x+=;int l=mm[y-x+];
return min(Min[x][l],Min[y-(<<l)+][l]);
} int a,b,c,d,lo,hi;
bool Check(int x,int n){
int l=,r=rk[c-]-,pl,pr;
while(l<=r){
if(Qmin(mid,rk[c-])>=x)r=mid-;
else l=mid+;
}pl=l;
l=rk[c-]+,r=n;
while(l<=r){
if(Qmin(rk[c-],mid)>=x)l=mid+;
else r=mid-;
}pr=r;
return Query(rt[pl-],rt[pr],,n,a,b-x+);
} int main(){
freopen("heoi2016_str.in","r",stdin);
freopen("heoi2016_str.out","w",stdout);
scanf("%d%d%s",&n,&Q,s);
for(;s[len];len++)r[len]=s[len];
DA(len+,);LCP(len);Prepare(len);
for(int i=;i<=len;i++)
Insert(rt[i-],rt[i],,len,sa[i]+,);
while(Q--){
scanf("%d%d%d%d",&a,&b,&c,&d);
lo=,hi=min(b-a+,d-c+);
while(lo<=hi){
int MID=(lo+hi)>>;
if(Check(MID,len))lo=MID+;
else hi=MID-;
}
printf("%d\n",hi);
}
return ;
}
字符串[未AC](后缀自动机):HEOI 2016 str的更多相关文章
- 【BZOJ1396】识别子串&【BZOJ2865】字符串识别(后缀自动机)
[BZOJ1396]识别子串&[BZOJ2865]字符串识别(后缀自动机) 题面 自从有了DBZOJ 终于有地方交权限题了 题解 很明显,只出现了一次的串 在\(SAM\)的\(right/e ...
- LOJ3049 [十二省联考2019] 字符串问题 【后缀自动机】【倍增】【拓扑排序】
题目分析: 建出后缀自动机,然后把A串用倍增定位到后缀自动机上,再把B串用倍增定位到后缀自动机上. SAM上每个点上的A串根据长度从小到大排序,建点,依次连边. 再对于SAM上面每个点,连到儿子的边, ...
- 2020牛客暑期多校训练营(第四场) C - Count New String (字符串,广义后缀自动机,序列自动机)
Count New String 题意: 定义字符串函数 \(f(S,x,y)(1\le x\le y\le n)\),返回一个长度为y-x+1的字符串,第 i 位是 \(max_{i=x...x+k ...
- BZOJ3473 字符串 【广义后缀自动机】
题目 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? 输入格式 第一行两个整数n,k. 接下来n行每行一个字符串. 输出格式 一行n个整数,第i个整数表 ...
- 字符串(多串后缀自动机):HDU 4436 str2int
str2int Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total S ...
- BZOJ 3473: 字符串 (广义后缀自动机)
/* 广义后缀自动机, 每次加入维护 该right集合的set, 然后可以更新所有的parent,最终能够出现在k个串中right集合也就是set大小大于等于k的部分 这样的话就给了我们要跳的节点加了 ...
- 【BZOJ3756】Pty的字符串(广义后缀自动机)
题意: 思路:论文题 建立Trie树的后缀自动机需要换这个长的板子 #include<bits/stdc++.h> using namespace std; typedef long lo ...
- 【BZOJ3473&BZOJ3277】字符串(广义后缀自动机)
题意:给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? 本质相同的子串算多个. 对于 100% 的数据,1<=n,k<=10^5,所有字符串总 ...
- 字符串(广义后缀自动机):BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 843 Solved: 510[Submit][St ...
随机推荐
- 各种语言HMAC SHA256实现
语言包含: Javascript ,PHP,Java,Groovy,C#,Objective C,Go,Ruby,Python,Perl,Dart,Swift,Rust,Powershell. Jav ...
- Http,Https (SSL)的Url绝对路径,相对路径解决方案Security Switch 4.2 中文帮助文档 分类: ASP.NET 2014-10-28 14:09 177人阅读 评论(1) 收藏
下载地址1:https://securityswitch.googlecode.com/files/SecuritySwitch%20v4.2.0.0%20-%20Binary.zip 下载地址2:h ...
- EntityFramework 中生成的类加注释
EF5在生成实体类时获取不到数据库中表的说明字段,需要使用单独的t4模板来获取 下载文件 将文件与edmx 放同一文件夹 1.在生成类的t4模板中加入 <#@ include file=&quo ...
- java异常类的使用
1.异常的概念 什么是异常?程序出错分为两部分,编译时出粗和运行时出错.编译时出错是编译器在编译源码时发生的错误: 运行时出错是在编译通过,在运行时出现的错误.这种情况叫异常. 例如:数组越界,除数为 ...
- 【读书笔记】管道和FIFO
管道 提供一个单路(单向)数据流,可以为两个不同进程提供进程间的通信手段 #include <unistd.h> ]); 返回两个文件描述符,fd[0](读) 和 fd[1](写) 管道间 ...
- Word 中标题的编号变成黑框
问题: 在使用Word编写文档时,提前拟好的标题编号会突然变成黑框(黑色的方框,黑色的矩形),如下图 解决方案: 1.将光标定位到标题中,紧邻黑框的右侧 2.按键盘左方向键使方框变成黑色 4.按键盘的 ...
- C# Base64编码/解码
一.编码规则 Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码.它将需要编码的数据拆分成字节数组.以3个字节为一组.按顺序排列24 位数据,再把这24位数据分成4 ...
- WordPress4.1新的函数介绍
wordpress 4.1也更新了一阵子了,作为一般用户最关系的就是新的wordpress主题,作为开发者,新增的函数也给我们带来了更多的便捷和惊喜,今天就转载一篇介绍wordpress4.1中新增的 ...
- SGU 143.Long Live the Queen(女王万岁)
时间限制:0.25s 空间限制:4M 题意: 有n(n<=16000)个小镇,每两个小镇有且仅有一条路径相连.每个小镇有一个收益x(-1000<=x<=1000). 现在要求,选择一 ...
- SGU 231.Prime Sum
题意: 求有多少对质数(a,b)满足a<=b 且a+b也为质数.(a+b<=10^6) Solution: 除了2之外的质数都是奇数,两个奇数的和是偶数,不可能是质数.所以题目就是求差为2 ...