QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#871879#9514. 研心NineSunsCompile Error//C++147.1kb2025-01-25 22:33:132025-01-25 22:33:13

Judging History

你现在查看的是最新测评结果

  • [2025-01-25 22:33:13]
  • 评测
  • [2025-01-25 22:33:13]
  • 提交

answer

#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pii pair <int, int>
#define fi first
#define se second

using namespace std;
const int N = 4e5+5, B = 200, inf = 0x3f3f3f3f; 
int n, m, ls[N], rs[N], bg[N], rv[N], lv[N], id[N]; 
string a[N], b[N]; 

int r[N]; 
int gmax (string s) {
    int res = 1; 
    r[0] = 1; 
    for (int i = 1, j = 0, mr = 0;i < s.size();i++) {
        r[i] = 0; 
        if (mr >= i) r[i] = min(r[j+j-i], mr-i+1); 
        while (i-r[i] >= 0 && i+r[i] < s.size() && s[i-r[i]] == s[i+r[i]]) r[i]++; 
        if (i+r[i]-1 > mr) mr = i+r[i]-1, j = i; 
        res = max(res, r[i]); 
    }
    return res; 
}

struct _SA {
    int rk[N], sa[N], cnt[N], ts[N], tk[N], ht[N], id[N], st[25][N]; 
    void SA (int *s, int n) {
        int m = 0; 
        for (int i = 1;i <= n;i++) m = max(m, s[i]); 
        memset(cnt, 0, m+1<<2); 
        for (int i = 1;i <= n;i++) cnt[rk[i] = s[i]]++; 
        for (int i = 1;i <= m;i++) cnt[i] += cnt[i-1];
        for (int i = 1;i <= n;i++) sa[cnt[rk[i]]--] = i; 
        // for (int i = 1;i <= n;i++) cout << sa[i] << " "; cout << endl; 
        for (int p = 0, t = 1; ;t <<= 1, m = p, p = 0) {
            for (int i = n-t+1;i <= n;i++) ts[++p] = i;
            for (int i = 1;i <= n;i++) if (sa[i] > t) ts[++p] = sa[i]-t; 
            // cout << "P:" <<p <<" " << n << " " << t << endl; 
            // for (int i = 1;i <= p;i++) cout << ts[i] << " "; cout << endl; 
            memset(cnt, 0, m+1<<2); memcpy(tk, rk, n+1<<2); 
            for (int i = 1;i <= p;i++) cnt[rk[ts[i]]]++;  
            for (int i = 1;i <= m;i++) cnt[i] += cnt[i-1]; 
            for (int i = 1;i <= p;i++) sa[cnt[rk[ts[i]]]--] = ts[i]; 
            // for (int i = 1;i <= n;i++) cout << sa[i] << " "; cout << endl; 
            rk[sa[1]] = p = 1;
            for (int i = 2;i <= n;i++) rk[sa[i]] = tk[sa[i-1]] == tk[sa[i]] && tk[sa[i-1]+t] == tk[sa[i]+t] ? p : ++p; 
            // cout <<p <<" " <<n<<endl; 
            if (p == n) break; 
        }    
        int k = 0; 
        for (int i = 1;i <= n;i++) {
            if (k) k--; 
            if (rk[i] == 1) continue;  
            whlie (i+k <= n && sa[rk[i]-1]+k <= n && s[i+k] == s[sa[rk[i]-1]+k]) k++; 
            ht[rk[i]] = k; 
        }
        // for (int i = 1;i <= n;i++) cout << ht[i] << " "; cout << endl; 
        for (int i = 1;i <= n;i++) st[0][i] = ht[i]; 
        for (int i = 1;i < 25;i++) {
            for (int j = 1;j+(1<<i)-1 <= n;j++) st[i][j] = min(st[i-1][j], st[i-1][j+(1<<i-1)]); 
        }
    }
    inline int LCP (int x, int y) {
        x = rk[x]; y = rk[y]; 
        if (x > y) swap(x, y); 
        int k = __lg(y-x);
        return min(st[k][x+1], st[k][y-(1<<k)+1]); 
    }
}sa; 
struct sgt {
    int o[N<<2], s[N<<2]; 
    inline void push_up (int p, int sz) {
        s[p] = o[p] ? sz : (sz > 1 ? s[p<<1]+s[p<<1|1] : 0); 
    }
    void build (int p, int l, int r) {
        o[p] = 0; 
        if (l == r) return s[p] = 0, void(); 
        int mid = l+r>>1; 
        build(p<<1, l, mid); build(p<<1|1, mid+1, r); 
        push_up(p, r-l+1); 
    }
    void uadd (int p, int l, int r, int tl, int tr, int k) {
        if (tl <= l && r <= tr) {
            o[p] += k; push_up(p, r-l+1); 
            return; 
        }
        int mid = l+r>>1; 
        if (tl <= mid) uadd(p<<1, l, mid, tl, tr, k); 
        if (tr > mid) uadd(p<<1|1, mid+1, r, tl, tr, k); 
        push_up(p, r-l+1); 
    }
}tr; 

struct node {
    int l, r, v; 
}; 
vector <node> ad[N]; 
ll solve (int k) {
    for (int i = 1;i <= n;i++) ad[i].clear(); 
    for (int I = 1;I <= n;I++) {
        int i = ls[I];
        int d = gmax(a[i]); 
        if (d < k) 
        for (int j = 0;j < a[i].size();j++) {
            if (r[j] <= j) continue; 
            int s = sa.rk[bg[i]+j+r[j]]; 
            int x = lower_bound(rv+1, rv+1+m, s)-rv; 
            int tl = 1, tr = x; 
            while (tl < tr) {
                int mid = tl+tr>>1; 
                if (sa.LCP(id[rs[mid]], bg[i]+j+r[j]) >= k-r[j]) tr = mid; 
                else tl = mid+1; 
            }
            int sl = tl; 
            tl = x-1, tr = m; 
            while (tl < tr) {
                int mid = tl+tr+1>>1; 
                if (sa.LCP(id[rs[mid]], bg[i]+j+r[j]) >= k-r[j]) tl = mid;
                else tr = mid-1; 
            }
            int sr = tr; 
            if (sl <= sr) ad[I].pb((node){sl, sr, 1}), ad[I+1].pb((node){sl, sr, -1}); 
        }
        else { 
            ad[I].pb((node){1, m, 1}); ad[I+1].pb((node){1, m, -1});  
        }
    } 
    for (int I = 1;I <= m;I++) {
        int i = rs[I]; 
        int d = gmax(b[i]); 
        if (d < k) 
        for (int j = 0;j < b[i].size();j++) {
            if (r[j] <= j) continue; 
            int s = sa.rk[id[i]+j+r[j]]; 
            // cout << "CHK:" << i << " " << r[j] << " " << j << " " << sb.rk[id[i]+j+r[j]] << endl; 
            int x = lower_bound(lv+1, lv+1+n, s)-lv; 
            // cout << bg[ls[3]] << " " << id[i]+j+r[j] << " " << sb.LCP(bg[ls[3]], id[i]+j+r[j]) << endl; 
            int tl = 1, tr = x; 
            while (tl < tr) {
                int mid = tl+tr>>1; 
                if (sa.LCP(bg[ls[mid]], id[i]+j+r[j]) >= k-r[j]) tr = mid; 
                else tl = mid+1; 
            }
            int sl = tl; 
            tl = x-1, tr = n; 
            while (tl < tr) {
                int mid = tl+tr+1>>1; 
                if (sa.LCP(bg[ls[mid]], id[i]+j+r[j]) >= k-r[j]) tl = mid;
                else tr = mid-1; 
            }
            int sr = tr; 
            if (sl <= sr) ad[sl].pb((node){I, I, 1}), ad[sr+1].pb((node){I, I, -1}); 
        }
        else {
            ad[1].pb((node){I, I, 1}); 
        }
        // cout << "B:" << I << " " << sl << " " << sr << endl;  
    } 
    tr.build(1, 1, m);
    ll res = 0; 
    for (int i = 1;i <= n;i++) {
        for (auto j : ad[i]) tr.uadd(1, 1, m, j.l, j.r, j.v); 
        res += tr.s[1]; 
    }
    // cout << k << " " << res << endl; 
    return res; 
}
int ds[N], al, am[N], bm[N]; 

int main () {
    cin >> n >> m; 
    for (int i = 1;i <= n;i++) cin >> a[i]; 
    for (int i = 1;i <= m;i++) cin >> b[i];
    ll ans = 0; 
    for (int i = 1;i <= n;i++) { 
        bg[i] = al+1; 
        reverse(a[i].begin(), a[i].end()); 
        for (auto j : a[i]) ds[++al] = j; ds[++al] = i+'z'; 
    }
    for (int i = 1;i <= m;i++) {
        string ns = b[i];
        id[i] = al+1; 
        for (auto j : b[i]) ds[++al] = j; ds[++al] = i+n+'z'; 
    } 
    sa.SA(ds, al); 
    for (int i = 1;i <= m;i++) rs[i] = i; 
    sort(rs+1, rs+1+m, [&](int x, int y){ return sa.rk[id[x]] < sa.rk[id[y]]; }); 
    for (int i = 1;i <= m;i++) rv[i] = sa.rk[id[rs[i]]];  
    for (int i = 1;i <= n;i++) ls[i] = i; 
    sort(ls+1, ls+1+m, [&](int x, int y){ return sa.rk[bg[x]] < sa.rk[bg[y]]; }); 
    for (int i = 1;i <= n;i++) lv[i] = sa.rk[bg[ls[i]]]; 
    for (int i = 1;i <= 10000;i++) ans += solve(i); 
    for (int i = 1;i <= n;i++) am[i] = gmax(a[i]); 
    for (int i = 1;i <= m;i++) bm[i] = gmax(b[i]); 
    cout << ans; 
    return 0; 
}

Details

answer.code: In member function ‘void _SA::SA(int*, int)’:
answer.code:56:13: error: ‘whlie’ was not declared in this scope
   56 |             whlie (i+k <= n && sa[rk[i]-1]+k <= n && s[i+k] == s[sa[rk[i]-1]+k]) k++;
      |             ^~~~~