救救孩子吧,调一晚上了
查看原帖
救救孩子吧,调一晚上了
361432
Froranzen楼主2022/4/26 03:06

求求了,蒟蒻真的调不出来了

#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;
}
2022/4/26 03:06
加载中...