板子求助/kel
查看原帖
板子求助/kel
160839
Prean楼主2020/10/25 10:42

RT,WA on 2/kel

#include<cstdio>
#include<cctype>
#define DEBUG printf("Baylor AK IOI!!!\n");
const int M=1e5+5;
int n,m,id[M],lg2[M],match[M];
char*it,s[M],str[M];
struct data{
	int val,pos;
	inline data(const int&val=0,const int&pos=0):val(val),pos(pos){}
	inline bool operator<(const data&it)const{
		return val==it.val?pos>it.pos:val<it.val;
	}
};
inline data max(const data&a,const data&b){
	return a<b?b:a;
}
struct Segment_Tree_Node{
	int L,R;data val;
}t[M<<8];
int tnc;
inline void pushup(const int&u){
	t[u].val=max(t[t[u].L].val,t[t[u].R].val);
}
void Add(int&u,int x,int L,int R){
	if(!u)u=++tnc;
	if(L==R)return void(t[u].val=data(++t[u].val.val,L));
	int mid=L+R>>1;
	if(x<=mid)Add(t[u].L,x,L,mid);
	else Add(t[u].R,x,mid+1,R);
	pushup(u);
}
int merge(int q,int p,int L,int R){
	if(!q||!p)return q|p;
	int id=++tnc;
	if(L==R){
		t[id].val=data(t[q].val.val+t[p].val.val,L);
		return id;
	}
	int mid=L+R>>1;
	t[id].L=merge(t[q].L,t[p].L,L,mid);
	t[id].R=merge(t[q].R,t[p].R,mid+1,R);
	pushup(id);
	return id;
}
data Query(int u,int l,int r,int L,int R){
	if(!u)return data(0,n+1);
	if(l<=L&&R<=r)return t[u].val;
	int mid=L+R>>1;data ans(0,n+1);
	if(l<=mid)ans=max(ans,Query(t[u].L,l,r,L,mid));
	if(r>mid)ans=max(ans,Query(t[u].R,l,r,mid+1,R));
	return ans;
}
struct Edge{
	int to;Edge*nx;
}e[M<<2],*h[M<<1],*tsc=e;
struct SAM_Node{
	int f,len;
	int chi[26];
}SAM[M<<1];
int cnt,lst,tot=1,d[M<<1],root[M<<1],f[M<<1][25];
inline void add(const int&u,const int&v){
	*tsc=(Edge){v,h[u]};h[u]=tsc++;
}
inline int Insert(const int&s){
	int q,p,nq,np,flag=0;
	p=lst;
	if(SAM[p].chi[s]&&SAM[SAM[p].chi[s]].len==SAM[p].len+1){
		return SAM[lst].chi[s];
	}
	np=lst=++tot;
	SAM[np].len=SAM[p].len+1;
	for(;p&&!SAM[p].chi[s];p=SAM[p].f)SAM[p].chi[s]=np;
	if(!p)SAM[np].f=1;
	else{
		q=SAM[p].chi[s];
		if(SAM[q].len==SAM[p].len+1)SAM[np].f=q;
		else{
			if(SAM[p].len+1==SAM[np].len)flag=1;
			SAM[nq=++tot]=SAM[q];
			SAM[np].f=SAM[q].f=nq;
			SAM[nq].len=SAM[p].len+1;
			for(;p&&SAM[p].chi[s]==q;p=SAM[p].f)SAM[p].chi[s]=nq;
		}
	}
	return flag?nq:np;
}
void DFS(int u){
	d[u]=d[f[u][0]=SAM[u].f]+1;
	for(int i=1;(1<<i)<=d[u];++i)f[u][i]=f[f[u][i-1]][i-1];
	for(Edge*E=h[u];E;E=E->nx){
		DFS(E->to);root[u]=merge(root[u],root[E->to],1,n);
	}
}
inline void Build(char*str){
	int i,s,now,len=0;
	for(i=2;i<=tot;++i)add(SAM[i].f,i);
	DFS(now=1);
	for(i=1;isalpha(s=str[i]);++i){
		s-=97;lg2[i]=lg2[i>>1]+1;
		while(now&&!SAM[now].chi[s])len=SAM[now=SAM[now].f].len;
		if(now)now=SAM[now].chi[s],++len;
		else now=1;
		id[i]=now;match[i]=len;
	}
}
signed main(){
	int i,k,l,r,L,R,now;lg2[i]=-1;
	scanf("%s",s+1);
	scanf("%d",&n);
	for(i=1;i<=n;++i){
		scanf("%s",str);it=str;lst=1;
		while(isalpha(*it))Add(root[lst=Insert(*it-97)],i,1,n),*it++=0;
	}
	Build(s);scanf("%d",&m);
	for(i=1;i<=m;++i){
		scanf("%d%d%d%d",&l,&r,&L,&R);
		now=id[R];
		if(R-L+1>match[R])printf("%d 0\n",l);
		else{
			for(k=lg2[d[now]];~k;--k){
				if(SAM[f[now][k]].len>=R-L+1)now=f[now][k];
			}
			data ans=Query(root[now],l,r,1,n);
			if(!ans.pos)ans.pos=l;
			printf("%d %d\n",ans.pos,ans.val);
		}
	}
}
2020/10/25 10:42
加载中...