求求了,蒟蒻真的调不出来了
#include <bits/stdc++.h>
#define rep(i, f, t) for(int i(f); i <= t; ++i)
#define re(i, t) for(int i(1); i <= t; ++i)
#define per(i, t, f) for(int i(t); i >= f; --i)
#define pe(i, t) for(int i(t); i >= 1; --i)
#define ste(i, f, t, s) for(int i(f); i <= t; i += s)
#define ets(i, t, f, s) for(int i(t); i >= f; i -= s)
#define each(i, x) for(auto &i : (x))
#define nx(i, u) for(int i(head[u]); i; i = e[i].nxt)
typedef long long ll;
typedef long double lb;
typedef unsigned long long ull;
// #define int long long
using namespace std;
// typedef pair <double, int> pdi;
typedef pair <int, int> pii;
// typedef pair <string, bool> psb;
#define pb push_back
#define fi first
#define se second
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
#define ix(l, r) ((l + r) | (l != r))
#define mp(i, j) (make_pair(i, j))
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define dinf 1000000000000.0
#define eps 1e-10
const int N = 5e5+5;
char s[N], t[N];
int n, m, Q, al, ar, bl, br;
struct Tree {
int sum, ans, l, r;
}tr[N*40];
int rt[N*2], tot;
inline void push_up (int now) {
int l = tr[now].l, r = tr[now].r;
if(tr[l].sum >= tr[r].sum) {
tr[now].sum = tr[l].sum;
tr[now].ans = tr[l].ans;
}
else {
tr[now].sum = tr[r].sum;
tr[now].ans = tr[r].ans;
}
}
void update (int &x, int l, int r, int pos) {
x = ++tot;
if(l == r) {
tr[x].ans = l;
++tr[x].sum;
return ;
}
int mid = (l + r) >> 1;
if(pos <= mid) update(tr[x].l, l, mid, pos);
else update(tr[x].r, mid + 1, r, pos);
push_up(x);
return ;
}
int merge (int x, int y, int l, int r) {
if(!x || !y) return x + y;
int z = ++tot;
if(l == r) {
tr[z].sum = tr[x].sum + tr[y].sum;
tr[z].ans = l;
return z;
}
int mid = (l + r) >> 1;
tr[z].l = merge(tr[x].l, tr[y].l, l, mid);
tr[z].r = merge(tr[x].r, tr[y].r, mid + 1, r);
push_up(z);
return z;
}
Tree query (int x, int l, int r, int dl, int dr) {
if(!x) return {0, 0, 0, 0};
if(dl <= l && r <= dr) return tr[x];
int mid = (l + r) >> 1;
Tree a = {0}, b = {0};
if(dl <= mid) a = query(tr[x].l, l, mid, dl, dr);
if(dr > mid) b = query(tr[x].r, mid + 1, r, dl, dr);
if(a.sum >= b.sum) return a;
return b;
}
struct node {
int len, link;
int nxt[26];
}st[N*2];
int siz = 1;
int insert (int c, int lst) {
int p = lst;
if(int q = st[p].nxt[c]) {
if(st[q].len == st[p].len + 1) return q;
int clone = ++siz;
st[clone].len = st[p].len + 1;
st[clone].link = st[q].link;
rep(i, 0, 25) st[clone].nxt[i] = st[q].nxt[i];
while(p && st[p].nxt[c] == q) {
st[p].nxt[c] = clone;
p = st[p].link;
}
st[q].link = clone;
return clone;
}
int cur = ++siz;
st[cur].len = st[p].len + 1;
while(p && !st[p].nxt[c]) {
st[p].nxt[c] = cur;
p = st[p].link;
}
if(!p) st[cur].link = 1;
else {
int q = st[p].nxt[c];
if(st[q].len == st[p].len + 1) st[cur].link = q;
else {
int clone = ++siz;
st[clone].len = st[p].len + 1;
st[clone].link = st[q].link;
rep(i, 0, 25) st[clone].nxt[i] = st[q].nxt[i];
while(p && st[p].nxt[c] == q) {
st[p].nxt[c] = clone;
p = st[p].link;
}
st[q].link = st[cur].link = clone;
}
}
return cur;
}
int q[N*2], b[N*2];
int a[N], len[N];
int fa[N*2][22];
void init () {
rep(i, 2, siz) ++b[st[i].len];
re(i, siz) b[i] += b[i-1];
rep(i, 2, siz) q[b[st[i].len]--] = i;
pe(i, siz-1) {
int u = q[i];
rt[st[u].link] = merge(rt[st[u].link], rt[u], 1, m);
}
re(i, siz-1) {
int u = q[i];
fa[u][0] = st[u].link;
re(j, 20) fa[u][j] = fa[fa[u][j-1]][j-1];
}
int p = 1, l = 0;
re(i, n) {
int c = s[i - 1] - 'a';
if(st[p].nxt[c]) {
++l;
p = st[p].nxt[c];
}
else {
while(p && !st[p].nxt[c]) p = st[p].link;
if(p) {
l = st[p].len + 1;
p = st[p].nxt[c];
}
else p = 1, l = 0;
}
a[i] = p, len[i] = l;
}
}
int main () {
scanf("%s", s);
n = strlen(s);
scanf("%d", &m);
re(i, m) {
scanf("%s", t);
int len = strlen(t);
int lst = 1;
re(j, len) lst = insert(t[j-1] - 'a', lst), update(rt[lst], 1, m, i);
}
init();
scanf("%d", &Q);
while(Q--) {
scanf("%d %d %d %d", &al, &ar, &bl, &br);
int p = a[br];
if(len[br] < br - bl + 1) {
printf("%d 0\n", al);
continue;
}
per(i, 20, 0) {
if(st[fa[p][i]].len >= br - bl + 1) p = fa[p][i];
}
Tree res = query(rt[p], 1, m, al, ar);
if(res.sum) printf("%d %d\n", res.ans, res.sum);
else printf("%d 0\n", al);
}
return 0;
}