真广义SAM WA on #2 求条
查看原帖
真广义SAM WA on #2 求条
609565
OtterZ楼主2024/9/7 16:53
#include<bits/stdc++.h>
using namespace std;
int n,m,ch[50009][26],last[50009],root[50009],samcnt,triecnt,node[500009],len[500009];
char s[500009],t[50009];
int mx[16000009],mxid[16000009],lc[16000009],rc[16000009],segcnt,qu[50009],head,tail;
void seg_add(int k,int l,int r,int pl,int val){
	if(l == r){
		mxid[k] = l;
		mx[k] += val;
		return;
	}
	int m = (l + r) >> 1;
	if(m >= pl){
		if(lc[k] == 0){
			segcnt++;
			lc[k] = segcnt;
			mxid[segcnt] = pl;
			mx[segcnt] = 0;
		}
		seg_add(lc[k],l,m,pl,val);
	}
	else{
		if(rc[k] == 0){
			segcnt++;
			rc[k] = segcnt;
			mxid[segcnt] = pl;
			mx[segcnt] = 0;
		}
		seg_add(rc[k],m + 1,r,pl,val);
	}
	if(mx[lc[k]] >= mx[rc[k]]){
		mx[k] = mx[lc[k]];
		mxid[k] = mxid[lc[k]];
	}
	else{
		mx[k] = mx[rc[k]];
		mxid[k] = mxid[rc[k]];
	}
}
int seg_mrg(int k1,int k2,int l,int r){
	if(k1 == 0 || k2 == 0)
		return k1 + k2;
	int o = ++segcnt;
	if(l == r){
		mx[o] = mx[k1] + mx[k2];
		mxid[o] = mxid[k1];
	}
	else{
		lc[o] = seg_mrg(lc[k1],lc[k2],l,(l + r) >> 1);
		rc[o] = seg_mrg(rc[k1],rc[k2],((l + r) >> 1) + 1,r);
		if(mx[lc[o]] >= mx[rc[o]]){
			mx[o] = mx[lc[o]];
			mxid[o] = mxid[lc[o]];
		}
		else{
			mx[o] = mx[rc[o]];
			mxid[o] = mxid[rc[o]];
		}
	}
	return o;
}
int ans1,ans2;
void gt_ans(int k,int l,int r,int ql,int qr){
//	printf("%d %d %d\n",k,l,r);
	if(l > qr || r < ql || k == 0)
		return;
	if((l >= ql && r <= qr) || (mxid[k] >= ql && mxid[k] <= qr)){
		if(ans2 < mx[k]){
			ans1 = mxid[k];
			ans2 = mx[k];
		}
		return;
	}
	int m = (l + r) >> 1;
	gt_ans(lc[k],l,m,ql,qr);
	gt_ans(rc[k],m + 1,r,ql,qr);
}
struct sam_node{
	int link,root,len;
	map<char,int>mp;
}sm[100009];
void trie_add(int cur,int u,int id){
	//printf("%d\n",cur);
	seg_add(root[cur],1,n,id,1);
	if(t[u] == '\0')
		return;
	if(ch[cur][t[u] - 'a'] == 0)
		ch[cur][t[u] - 'a'] = ++triecnt,root[triecnt] = ++segcnt;
	trie_add(ch[cur][t[u] - 'a'],u + 1,id);
}
void sam_extend(int last,char c,int node){
	sm[node].len = sm[last].len + 1;
	int p = last;
	while(p != 1 && sm[p].mp[c] == 0){
		sm[p].mp[c] = node;
		p = sm[p].link;
	}
	if(p == 1 && sm[p].mp[c] == 0){
		sm[1].mp[c] = node;
		sm[node].link = 1;
	}
	else{
		int q = sm[p].mp[c];
		if(sm[q].len == sm[p].len + 1)
			sm[node].link = q;
		else{
			int fq = ++samcnt;
			sm[fq].link = sm[q].link;
			sm[fq].len = sm[p].len + 1;
			sm[fq].root = 0;
			sm[fq].mp = sm[q].mp;
			sm[q].link = sm[node].link = fq;
			while(sm[p].mp[c] == q)
				sm[p].mp[c] = fq,p = sm[p].link;
		}
	}
}
void gt_sam(){
	samcnt = 1;
	sm[1].root = root[1];
	last[1] = 1;
	head = 1;
	tail = 1;
	qu[1] = 1;
	while(head <= tail){
		int d = qu[head];
		head ++;
		//printf("%d\n",d);
		for(int i = 0; i < 26; i ++){
			if(ch[d][i] != 0){
				samcnt ++;
				sm[samcnt].root = root[ch[d][i]];
				last[ch[d][i]] = samcnt;
				sam_extend(last[d],i + 'a',last[ch[d][i]]);
				qu[++tail] = ch[d][i];
			}
		}
	}
}
vector<int>e[100009];
int bz[100009][21];
void srh(int v);
void make_seg(){
	for(int i = 2; i <= samcnt; i ++){
		e[sm[i].link].push_back(i);
	}
	srh(1);
}
void srh(int v){
	//printf("%d\n",v);
	bz[v][0] = sm[v].link;
	for(int i = 1; i < 21; i ++){
		bz[v][i] = bz[bz[v][i - 1]][i - 1];
	}
	for(int i = 0; i < e[v].size(); i ++){
		srh(e[v][i]);
		sm[v].root = seg_mrg(sm[v].root,sm[e[v][i]].root,1,n);
	}
}
int main(){
	scanf(" %s",s);
	scanf("%d",&n);
	triecnt = 1;
	for(int i = 1; i <= n; i ++){
		scanf(" %s",t);
		trie_add(1,0,i);
	}
	gt_sam();
	make_seg();
	int nw = 1,nlen = 0;
	for(int i = 0; s[i] != '\0'; i ++){
		while(nw != 1 && sm[nw].mp[s[i]] == 0)
			nw = sm[nw].link,nlen = sm[nw].len;
		if(sm[nw].mp[s[i]] != 0)
			nw = sm[nw].mp[s[i]],nlen ++;
		node[i + 1] = nw;
		len[i + 1] = nlen;
		//printf("%d %d\n",node[i],len[i]);
	}
	scanf("%d",&m);
	while(m --){
		int l,r,ql,qr;
		scanf("%d %d %d %d",&l,&r,&ql,&qr);
		ans1 = l,ans2 = 0;
		if(qr - ql + 1 <= len[qr]){
			int o = node[qr];
			for(int i = 20; i >= 0; i --){
				if(sm[bz[o][i]].len >= qr - ql + 1)
					o = bz[o][i];
			}
			gt_ans(sm[o].root,1,n,l,r);
		}
		printf("%d %d\n",ans1,ans2);
	}
	return 0;
}
2024/9/7 16:53
加载中...