字符串[未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 ...
随机推荐
- 原创翻译:蓝牙(BLE)for iOS
About Core Bluetooth 简要:核心蓝牙框架提供了iOS和MAC 应用程序与BLE 设备进行无线通信所需要的类.通过该框架,应用程序可以扫描.发现BLE 外设,如心率.电子温度传感器等 ...
- 自定义HtmlHelper方法
原文:http://www.cnblogs.com/wenjiang/archive/2013/03/30/2990854.html HtmlHelper方法是ASP.NET MVC中非常强大的特性, ...
- Oracle dblink 使用详解
1.dblink简介 dblink(Database Link)数据库链接就是数据库的链接,跨本地数据库 2.使用语法详解 基本语法 CREATE [SHARED][PUBLIC] database ...
- 如何在xcode下面同时安装cocos2d-iphone 和 cocos2d-x模板,其实是因为很喜欢C++的缘故,当时学习的是前者,现在自己摸着石头过河了就(cocos2d-x安装失败 出错)
首先在Xcode下面配置两个模板的开发环境,其实一个开源库,一个C++移植,学习需要也是,我的mac上一直用的是cocos2d-iphone, 今天想试下cocos2d-x,安装的时间发现安装成功(我 ...
- (java)从零开始之--装饰者设计模式
装饰者设计模式:简单定义:增强一个类的功能,而且还可以让这些装饰类互相装饰. 应用场景:当要在某个功能的基础上扩充功能,并且扩充的功能具有大量排列组合,通过继承关系会衍生出大量子类,这时候用装饰者模式 ...
- 深度探索va_start、va_arg、va_end
采用C语言编程的时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的所有实际参数.但在某些情况下希望函数的参数个数可以根据需要确定.典型的例子有大家熟悉的函数printf().s ...
- Linux抓包工具tcpdump详解
tcpdump是一个用于截取网络分组,并输出分组内容的工具,简单说就是数据包抓包工具.tcpdump凭借强大的功能和灵活的截取策略,使其成为Linux系统下用于网络分析和问题排查的首选工具. tcpd ...
- SQL 结构化查询语言
SQL 结构化查询语言 一.数据库的必要性: >>作用:存储数据.检索数据.生成新的数据 1)可以有效结构化存储大量的数据信息,方便用户进行有效的检索和访问. 2)可以有效地保持数据信息的 ...
- jQuery备忘录--私家版
最近在看jQuery,总是看过了忘,不知道该怎么办?准备开启洗脑模式,日常念一念,紧箍咒加身. 1.jQuery方法第一步:ready=>加载html的骨架.而onload=>整个页面加载 ...
- ecshop标签大全
页面关键字:{$keywords} 页面标题:{$page_title} 产品分类:父分类列表 {foreach from=$categories item=cat } 父分类超链接 [u ...