代码40pts求调
查看原帖
代码40pts求调
204705
KiDDOwithTopTree楼主2022/6/13 17:44

或者哪位一样的提供建议吧qwq

#include<iostream>
#include<cstring>
using namespace std;
const int N=2e5+10;
struct smt_node{
	int ls,rs;
	int val;
};
smt_node smt[80*N];
int cnt;
inline int smt_copynode(int now){
	return smt[++cnt]=smt[now],cnt;
}
void smt_ins(int &now,int l,int r,int pos){
	if(!now) now=++cnt;
	smt[now].val|=1;
	if(l==r) return ;
	int mid=l+r>>1;
	if(pos<=mid) smt_ins(smt[now].ls,l,mid,pos);
	else smt_ins(smt[now].rs,mid+1,r,pos);
}
bool smt_query(int now,int l,int r,int ql,int qr){
	if(!now) return false;
	if(l>=ql&&r<=qr) return smt[now].val;
	int mid=l+r>>1,ans=false;
	if(ql<=mid) ans|=smt_query(smt[now].ls,l,mid,ql,qr);
	else ans|=smt_query(smt[now].rs,mid+1,r,ql,qr);
	return ans;
}
int smt_merge(int x,int y,int l,int r){
	if(!x||!y) return smt_copynode(x|y);
	x=smt_copynode(x),smt[x].val|=smt[y].val;
	int mid=l+r>>1;
	smt[x].ls=smt_merge(smt[x].ls,smt[y].ls,l,mid);
	smt[x].rs=smt_merge(smt[x].rs,smt[y].rs,mid+1,r);
	return x;
}
int posit[N];
struct prt_node{
	int fa,len;
	int rt;
};
struct suffix_automaton{
	prt_node prt[2*N];
	int ch[2*N][26];
	int last,tot;
	suffix_automaton(){
		last=tot=1;
	}
	void add(int c,int pos,int n){
		int p=last,np=last=++tot;
		prt[np].len=prt[p].len+1;
		smt_ins(prt[np].rt,1,n,pos);
		posit[pos]=np;
		while(p&&!ch[p][c]){
			ch[p][c]=np;
			p=prt[p].fa;
		}
		if(!p) return void(prt[np].fa=1);
		int q=ch[p][c];
		if(prt[q].len==prt[p].len+1)
			return void(prt[np].fa=q);
		int nq=++tot;
		prt[nq].len=prt[p].len+1;
		prt[nq].fa=prt[q].fa;
		prt[q].fa=prt[np].fa=nq;
		for(int i=0;i<26;i++)
			ch[nq][c]=ch[q][c];
		while(p&&ch[p][c]==q){
			ch[p][c]=nq;
			p=prt[p].fa;
		}
	}
};
suffix_automaton sam;
struct edge_node{
	int from,to;
	int nxt;
};
struct edge{
	edge_node e[2*N];
	int head[2*N],tot;
	edge(){
		memset(head,-1,sizeof head);
		tot=0;
	}
	inline void add(int from,int to){
		e[tot].from=from;
		e[tot].to=to;
		e[tot].nxt=head[from];
		head[from]=tot++;
	}
};
edge e;
int n,m;
int f[2*N][30],dep[2*N];
void dfs(int u,int fa){
	f[u][0]=fa,dep[u]=dep[fa]+1;
	for(int i=1;i<=20;i++) f[u][i]=f[f[u][i-1]][i-1];
	for(int i=e.head[u];~i;i=e.e[i].nxt){
		int v=e.e[i].to;dfs(v,u);
		sam.prt[u].rt=smt_merge(sam.prt[u].rt,sam.prt[v].rt,1,n);
	}
}
int get_pos(int x,int len){
	for(int i=20;i>=0;i--)
		if(sam.prt[f[x][i]].len>=len)
			x=f[x][i];
	return x;
}
bool check(int l1,int r1,int l2,int r2){
	int len=r1-l1+1,p=get_pos(posit[r1],len);
	return smt_query(sam.prt[p].rt,1,n,l2+len-1,r2);
}
int binary_search(int l1,int r1,int l2,int r2){
	int l=l1,r=r1,ans;
	while(l<=r){
		int mid=l+r>>1;
		if(check(l1,mid,l2,r2)) ans=mid,l=mid+1;
		else r=mid-1;
	}
	return ans-l1+1;
}
string s;
int main(){
	cin>>n>>m;
	cin>>s;
	for(int i=0;i<=n-1;i++)
		sam.add(s[i]-'a',i+1,n);
	for(int i=2;i<=sam.tot;i++)
		e.add(sam.prt[i].fa,i);
	dfs(1,0);
	for(int i=1;i<=m;i++){
		int l1,r1,l2,r2;
		cin>>l1>>r1>>l2>>r2;
		cout<<binary_search(l2,r2,l1,r1)<<'\n';
	}
}
2022/6/13 17:44
加载中...