本地可以过交上去RE求调
查看原帖
本地可以过交上去RE求调
943901
Caicity楼主2023/7/24 09:50
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,q,root[N],lim[N];
char s[N];
long long ans;
struct SGT{
	int ls[N*40],rs[N*40],val[N*40],tot;
	int cnt,head[N],net[N],to[N];
	void add(int u,int v){
		cnt++;
		to[cnt]=v;
		net[cnt]=head[u];
		head[u]=cnt;
	}
	void insert(int &p,int l,int r,int pos){
		if(!p) p=++tot;
		val[p]=pos;
		if(l==r) return ;
		int mid=(l+r)>>1;
		if(mid>=pos) insert(ls[p],l,mid,pos);
		else insert(rs[p],mid+1,r,pos);
	}
	int merge(int p,int q){
		if(!p||!q) return p+q;
		int np=++tot;
		ls[np]=merge(ls[p],ls[q]);
		rs[np]=merge(rs[p],rs[q]);
	}
	int query(int p,int l,int r,int L,int R){
		if(p==0||(L<=l&&r<=R)) return val[p];
		int mid=(l+r)>>1,ret=0;
		if(mid>=L) ret=max(ret,query(ls[p],l,mid,L,R));
		if(mid<R) ret=max(ret,query(rs[p],mid+1,r,L,R));
		return ret;
	}
}T;
struct node{
	int ch[26];
	int len,fa,tag;
}; 
struct SAM{
	node dian[N];
	int tot,las;
	int a[N],c[N],in[N];
	void insert(int c){
		int p=las,np=las=++tot; dian[np].len=dian[p].len+1; in[np]=1;
		for(;p&&!dian[p].ch[c];p=dian[p].fa) dian[p].ch[c]=np;
		if(!p) dian[np].fa=1;
		else{
			int q=dian[p].ch[c];
			if(dian[q].len==dian[p].len+1) dian[np].fa=q;
			else{
				int nq=++tot;
				dian[nq]=dian[q];
				dian[nq].len=dian[p].len+1;
				dian[q].fa=nq;
				for(;p&&dian[p].ch[c]==q;p=dian[p].fa) dian[p].ch[c]=nq;
			}
		}		
	}
	void calc(){
		for(int i=1;i<=n;i++) insert(s[i]-'a');
		for(int i=1;i<=tot;i++) ++c[dian[i].len];
		for(int i=1;i<=tot;i++) c[i]+=c[i-1];
		for(int i=1;i<=tot;i++) a[c[dian[i].len]--]=i;
		for(int i=tot;i>=0;i--){
			int p=a[i];
			if(in[p]) T.insert(root[p],1,n,dian[p].len);
			root[dian[p].fa]=T.merge(root[dian[p].fa],root[p]);
		}
	}
}A;
struct SAM2{
	node dian[N];
	int tot,las;
	int a[N],c[N],tag[N];
	void init(){
		tot=las=1,memset(dian[1].ch,0,sizeof dian[1].ch);
	}
	int newnode(){
		++tot;
		memset(dian[tot].ch,0,sizeof dian[tot].ch);
		return tot;
	}
	void insert(int c){
		int p=las,np=las=newnode(); dian[np].tag=dian[np].len=dian[p].len+1;
		for(;p&&!dian[p].ch[c];p=dian[p].fa) dian[p].ch[c]=np;
		if(!p) dian[np].fa=1;
		else{
			int q=dian[p].ch[c];
			if(dian[q].len==dian[p].len+1) dian[np].fa=q;
			else{
				int nq=newnode();
				dian[nq]=dian[q];
				dian[nq].len=dian[p].len+1;
			}
		}
	}
	void solve(){
		int l,r;
		string S;
		cin>>S;
		for(int i=1;i<=S.size();i++) s[i]=S[i-1];
		scanf("%d%d",&l,&r);
		init();
		m=strlen(s+1);
		for(int i=1,len=0,p=1;i<=m;i++){
			int c=s[i]-'a';
			insert(c);
			while(1){
				if(A.dian[p].ch[c]&&T.query(root[A.dian[p].ch[c]],1,n,l+len,r)){
					++len,p=A.dian[p].ch[c];
					break;
				}
				if(len==0) break;
				--len;
				if(len==A.dian[A.dian[p].fa].len) p=A.dian[p].fa;
			}
			lim[i]=len;
		}
		ans=0;
		for(int i=2;i<=tot;i++) ans+=max(0,dian[i].len-max(dian[dian[i].fa].len,lim[dian[i].tag]));
		printf("%lld\n",ans);
	}
}B;
int main(){
	string S;
	cin>>S;
	for(int i=1;i<=S.size();i++) s[i]=S[i-1];
	n=strlen(s+1);
	A.calc();
	scanf("%d",&q);
	while(q--) B.solve();
	return 0;
}
2023/7/24 09:50
加载中...