MnZn 0pts求调
查看原帖
MnZn 0pts求调
716965
L_zaa_L楼主2023/12/29 14:41
#include<bits/stdc++.h>
#define int long long
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
#define rep(i,b) for(int i=1;i<=b;i++)
using namespace std;
//char buf[(1<<21)+5],*p1,*p2;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
void chmx(int &x,int y){(x<y)&&(x=y);}
void chmn(int &x,int y){(x>y)&&(x=y);}
const int N=2e5+5;
inline int read(){
	int f=0,x=0;
	char ch=getchar();
	while(!isdigit(ch)){f|=(ch=='-');ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return f?-x:x;
}
char n,s[N];
int lnk[N];
map<int,int>ch[N];
int len[N],last=1,tot=1;
int tag[N],a[N];
inline void insert(int c){
	int p=last,cur=++tot;
	last=cur;
	len[cur]=len[p]+1;
	for(;p&&!ch[p].count(c);p=lnk[p]) ch[p][c]=cur;
	if(!p) lnk[cur]=1;
	else{
		int q=ch[p][c];
		if(len[p]+1==len[q]) lnk[cur]=q;
		else{
			int copy=++tot;
			len[copy]=len[p]+1;lnk[copy]=lnk[q];
			ch[copy]=ch[q];
			lnk[q]=lnk[cur]=copy;
			for (;ch[p].count(c)&&p;p=lnk[p]){
				if(ch[p][c]==q)ch[p][c]=copy;
				else break;
			}
		}	
	}
}
int pos[N],rt[N];
int cnt;
struct SegmentTree{
	int l,r;
	int v;
}tr[N<<3];
inline void modify(int &x,int l,int r,int k){
	if(!x) x=++cnt;
	tr[x].v++;
	if(l==r) return ;
	int mid=(l+r)>>1;
	if(k<=mid) modify(tr[x].l,l,mid,k);
	else modify(tr[x].r,mid+1,r,k);
}
int merge(int x,int y){
	if(!x||!y) return x|y;
	int nw=++cnt;
	tr[nw].v=tr[x].v+tr[y].v;
	tr[nw].l=merge(tr[x].l,tr[y].l);
	tr[nw].r=merge(tr[x].r,tr[y].r);
	return nw;
}


int query(int x,int l,int r,int L,int R){
	if(!x) return 0;
	if(L<=l&&r<=R) return tr[x].v;
	int mid=(l+r)>>1;
	int res=0;
	if(L<=mid) res+=query(tr[x].l,l,mid,L,R);
	if(R>mid) res+=query(tr[x].r,mid+1,r,L,R);
	return res;
}
int fa[N][21];
bool ask(int u,int ln,int l,int r){
	for(int i=20;i>=0;i--)
		if(fa[u][i]&&len[fa[u][i]]>=ln) u=fa[u][i];
	return query(rt[u],1,n,l+ln-1,r);
}
inline void work(){
	for(int i=1;i<=tot;i++) fa[i][0]=lnk[i];
	for(int i=1;i<=tot;++i) tag[len[i]]++;
	for(int i=1;i<=tot;++i) tag[i]+=tag[i-1];
	for(int i=tot;i>=1;--i) a[tag[len[i]]--]=i;
	for(int i=tot;i>1;--i){
		rt[lnk[a[i]]]=merge(rt[a[i]],rt[lnk[a[i]]]);
	}
	for(int k=1;k<=20;k++)
		for(int i=1;i<=tot;i++)
			fa[i][k]=fa[fa[i][k-1]][k-1];
}
signed main(){
	//freopen("CF55D.in","r",stdin);
	//freopen("zaa.out","w",stdout);
	n=read(); 
	int Q=read();
	scanf("%s",s+1);
	reverse(s+1,s+n+1);
	for(int i=1;i<=n;i++){
		insert(s[i]-'a');
		pos[i]=last;
		modify(rt[last],1,n,i);
	}
	work();
	while(Q--){
		int l1=n-read()+1,r1=n-read()+1,l2=n-read()+1,r2=n-read()+1;
		int l=0,r=min(l1-r1+1,l2-r2+1);
		int ans=0;
		while(l<=r){
			int mid=(l+r)>>1;
			if(ask(pos[l2],mid,r1,l1)) l=mid+1,ans=mid;
			else r=mid-1;
		}
		printf("%lld\n",ans);
	}
    return 0;
}
2023/12/29 14:41
加载中...