萌新刚学OI
查看原帖
萌新刚学OI
173660
zhoukangyang楼主2020/9/27 22:00

不要无意义讨论,要不然蒟蒻气到删帖!

第二个点的第三个询问 WA 了,测试点太大复制不下来。

#include<bits/stdc++.h>
#define L(i, j, k) for(int i = j; i <= k; i++) 
#define R(i, j, k) for(int i = j; i >= k; i--) 
using namespace std;
const int N = 1e6 + 7;
const int cN = 26;
const int M = 2e6;
int n, tn, m, Q, ls[N];
int jp[N][22];
struct Max {
	int maxn, maxid;
};
bool operator < (Max aa, Max bb) { return aa.maxn < bb.maxn ? 1 : (aa.maxn == bb.maxn && aa.maxid < bb.maxid); }
struct SegmentTree {
	int sum[M], ch[M][2], tot;
	Max maxn[M];
	void add(int &id, int L, int R, int wz) {
		if(!id) id = ++tot;
		sum[id]++;
		if(L == R) return (void)(maxn[id].maxid = L, maxn[id].maxn = sum[id]);
		int mid = (L + R) / 2;
		if(wz <= mid) add(ch[id][0], L, mid, wz);
		else add(ch[id][1], mid + 1, R, wz);
		maxn[id] = max(maxn[ch[id][0]], maxn[ch[id][1]]);
	}
	int merge(int x, int y, int L, int R) { // sto Rainbow_sjy orz
		if(!x || !y) return x | y;
		int Rainbow_sjy = ++tot, mid = (L + R) / 2;
		sum[Rainbow_sjy] = sum[x] + sum[y];
		if(L == R) {
			maxn[Rainbow_sjy].maxid = L, maxn[Rainbow_sjy].maxn = sum[Rainbow_sjy];
			return Rainbow_sjy;
		}
		ch[Rainbow_sjy][0] = merge(ch[x][0], ch[y][0], L, mid);
		ch[Rainbow_sjy][1] = merge(ch[x][1], ch[y][1], mid + 1, R);
		maxn[Rainbow_sjy] = max(maxn[ch[Rainbow_sjy][0]], maxn[ch[Rainbow_sjy][1]]);
		return Rainbow_sjy;
	}
	Max query(int id, int L, int R, int l, int r) {
		if(id == 0) return maxn[id];
		if(l == L && R == r) return maxn[id];
		int mid = (L + R) / 2;
		if(r <= mid) return query(ch[id][0], L, mid, l, r);
		if(l > mid) return query(ch[id][1], mid + 1, R, l, r);
		return max(query(ch[id][0], L, mid, l, mid), query(ch[id][1], mid + 1, R, mid + 1, r));
	}
} seg;
struct SAM {
	int head[N], fa[N], len[N], ch[N][cN], las = 1, tot = 1;
	void copy(int x, int y) {
		L(i, 0, cN - 1) ch[y][i] = ch[x][i];
		len[y] = len[x], fa[y] = fa[x];
	}
	void ins(int x, int y) {
		if(ch[las][x] && len[ch[las][x]] == len[las] + 1) {
			las = ch[las][x];
			if(y) seg.add(head[las], 1, m, y);//, cout << "nederlandakioi!/qq\n";
			return;
		}
		int p = las, now = las = ++tot;
		len[now] = len[p] + 1;
		if(y) seg.add(head[now], 1, m, y);//, cout << "George1123akioi!/qq\n";
		for(; p && !ch[p][x]; p = fa[p]) ch[p][x] = now;
		if(!p) fa[now] = 1;
		else {
			int pto = ch[p][x];
			if(len[pto] == len[p] + 1) fa[now] = pto;
			else {
				int sp = ++tot;
				copy(pto, sp), len[sp] = len[p] + 1;
				fa[pto] = fa[now] = sp;
				for(; p && ch[p][x] == pto; p = fa[p]) ch[p][x] = sp;
			}
		}
	}
} sam;
int c[N], q[N];
void work() {
	L(i, 1, sam.tot) c[sam.len[i]]++;
	L(i, 1, sam.tot) c[i] += c[i - 1];
	L(i, 1, sam.tot) q[c[sam.len[i]]--] = i;
	R(i, sam.tot, 1) sam.head[sam.fa[q[i]]] = seg.merge(sam.head[sam.fa[q[i]]], sam.head[q[i]], 1, m);
}
void getans(int x, int len, int L, int R) {
	R(i, 20, 0) if(sam.len[jp[x][i]] >= len) x = jp[x][i];
	Max gg = seg.query(sam.head[x], 1, m, L, R);
	if(gg.maxn) printf("%d %d\n", gg.maxid, gg.maxn);
	else printf("%d 0\n", L);
}
char s[N], ss[N];
int main() {
	scanf("%s", ss + 1), n = strlen(ss + 1);
	L(i, 1, n) sam.ins(ss[i] - 'a', 0);
	scanf("%d", &m);
	L(t, 1, m) {
		scanf("%s", s), n = strlen(s);
		L(i, 0, n - 1) sam.ins(s[i] - 'a', t);
	}
	work();
	int now = 1;
	n = strlen(ss + 1);
	L(i, 1, n) ls[i] = now = sam.ch[now][ss[i] - 'a'];
	L(i, 1, sam.tot) jp[i][0] = sam.fa[i];
	L(j, 1, 20) L(i, 1, sam.tot) jp[i][j] = jp[jp[i][j - 1]][j - 1];
	scanf("%d", &Q);
	while(Q--) {
		int a, b, c, d;
		scanf("%d%d%d%d", &a, &b, &c, &d);
		getans(ls[d], d - c + 1, a, b);	
	}
	return 0;
}
2020/9/27 22:00
加载中...