QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#626479#7901. Basic Substring StructureMiniLongTL 0ms24044kbC++207.5kb2024-10-10 09:31:422024-10-10 09:31:47

Judging History

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

  • [2024-10-10 09:31:47]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:24044kb
  • [2024-10-10 09:31:42]
  • 提交

answer

#include <bits/stdc++.h>
#define _rep(i, x, y) for(int i = x; i <= y; ++i)
#define _req(i, x, y) for(int i = x; i >= y; --i)
#define _rev(i, u) for(int i = head[u]; i; i = e[i].nxt)
#define pb push_back
#define fi first
#define se second
#define mst(f, i) memset(f, i, sizeof f)
using namespace std;
#ifdef ONLINE_JUDGE
#define debug(...) 0
#else
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#endif
typedef long long ll;
typedef pair<int, int> PII;
namespace fastio{
    #ifdef ONLINE_JUDGE
    char ibuf[1 << 20],*p1 = ibuf, *p2 = ibuf;
    #define get() p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, 1 << 20, stdin), p1 == p2) ? EOF : *p1++
    #else
    #define get() getchar()
    #endif
    template<typename T> inline void read(T &t){
        T x = 0, f = 1;
        char c = getchar();
        while(!isdigit(c)){
            if(c == '-') f = -f;
            c = getchar();
        }
        while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
        t = x * f;
    }
    template<typename T, typename ... Args> inline void read(T &t, Args&... args){
        read(t);
        read(args...);
    }
    template<typename T> void write(T t){
        if(t < 0) putchar('-'), t = -t;
        if(t >= 10) write(t / 10);
        putchar(t % 10 + '0');
    }
    template<typename T, typename ... Args> void write(T t, Args... args){
        write(t), putchar(' '), write(args...);
    }
    template<typename T> void writeln(T t){
        write(t);
        puts("");
    }
    template<typename T> void writes(T t){
        write(t), putchar(' ');
    }
    #undef get
};
using namespace fastio;
#define multitest() int T; read(T); _rep(tCase, 1, T)
namespace Calculation{
    const ll mod = 998244353;
    ll ksm(ll p, ll h){ll base = p % mod, res = 1; while(h){if(h & 1ll) res = res * base % mod; base = base * base % mod, h >>= 1ll;} return res;}
    void dec(ll &x, ll y){x = ((x - y) % mod + mod) % mod;}
    void add(ll &x, ll y){x = (x + y) % mod;}
    void mul(ll &x, ll y){x = x * y % mod;}
    ll sub(ll x, ll y){return ((x - y) % mod + mod) % mod;}
    ll pls(ll x, ll y){return ((x + y) % mod + mod) % mod;}
    ll mult(ll x, ll y){return x * y % mod;}
}
using namespace Calculation;
const int N = 2e5 + 5;
int n, s[N];
namespace SA{
    int m, x[N], y[N], sa[N], rk[N], c[N], ht[N], f[N][25];
    void build(){
        m = n;
        _rep(i, 1, n) c[x[i] = s[i]]++;
        _rep(i, 1, m) c[i] += c[i - 1];
        _req(i, n, 1) sa[c[x[i]]--] = i;
        for(int k = 1; k <= n; k <<= 1){
            int p = 0;
            _rep(i, n - k + 1, n) y[++p] = i;
            _rep(i, 1, n) if(sa[i] > k) y[++p] = sa[i] - k;
            _rep(i, 1, m) c[i] = 0;
            _rep(i, 1, n) c[x[y[i]]]++;
            _rep(i, 1, m) c[i] += c[i - 1];
            _req(i, n, 1) sa[c[x[y[i]]]--] = y[i];
            p = y[sa[1]] = 1;
            _rep(i, 2, n) y[sa[i]] = (x[sa[i]] == x[sa[i - 1]] && x[sa[i] + k] == x[sa[i - 1] + k]) ? p : ++p;
            swap(x, y);
            if(p >= n) break;
            m = n;
        }
        _rep(i, 1, n) rk[sa[i]] = i;
        int k = 0; ht[1] = 0;
        _rep(i, 1, n){
            if(rk[i] == 1) continue;
            if(k) --k;
            while(s[i + k] == s[sa[rk[i] - 1] + k]) ++k;
            ht[rk[i]] = k;
        }
        _rep(i, 1, n) f[i][0] = ht[i];
        _rep(i, 1, 20) _rep(j, 1, n - (1 << i) + 1) f[j][i] = min(f[j][i - 1], f[j + (1 << i - 1)][i - 1]);
    }
    int lcp(int x, int y){
        if(x > n || y > n || x < 1 || y < 1) return 0;
        if(x == y) return n - x + 1;
        x = rk[x], y = rk[y]; if(x > y) swap(x, y); x++;
        int k = __lg(y - x + 1);
        return min(f[x][k], f[y - (1 << k) + 1][k]);
    }
    void clr(){
        _rep(i, 1, n) x[i] = y[i] = sa[i] = rk[i] = c[i] = ht[i] = 0, mst(f[i], 0);
        m = 0;
    }
}
using SA::lcp;
ll ans, z[N], r[N], f[N], g[N], nxt[N], res[N];
vector<int> h[N];
int lcp(int x, int y, int p, int c){
    int lst = s[p]; s[p] = c;
    int cur = min(lcp(x, y), p - x);
    if(cur < p - x || s[y + cur] != s[x + cur]) return s[p] = lst, cur;
    cur += lcp(x + cur + 1, y + cur + 1) + 1;
    return s[p] = lst, cur;
}
int calc(int p, int c){
    int lst = s[p]; s[p] = c;
    int tot = 0;
    _rep(i, 1, n){
        int cur = 0;
        _rep(j, 1, n - i + 1){
            if(s[i + j - 1] != s[j]) break;
            cur++;
        }
        tot += cur;
    }
    s[p] = lst;
    return tot;
}
ll pre[N], suf[N];
vector<PII> v[N];
void clr(){
    ans = 0;
    _rep(i, 1, n) z[i] = r[i] = f[i] = g[i] = nxt[i] = res[i] = 0, h[i].clear(), pre[i] = suf[i] = 0, v[i].clear();
    SA::clr();
}
int main(){
    multitest(){
        read(n);
        _rep(i, 1, n) read(s[i]);
        SA::build();
        _rep(i, 1, n){
            z[i] = lcp(i, 1), ans += z[i], r[i] = i + z[i] - 1;
            if(z[i] < n - i + 1){
                nxt[i] = s[z[i] + 1];
                f[i] = lcp(z[i] + 2, i + z[i] + 1, r[i] + 1, nxt[i]) + 1;
                if(z[i] < i - 1) g[i] = lcp(z[i + 2], i + z[i] + 1) + 1;
            }
            // debug("(%d,%d) f:%d\n", z[i], r[i], f[i]);
        }
        /*work 1*/
        vector<int> p;
        _rep(i, 2, n) p.pb(i);
        sort(p.begin(), p.end(), [](int x, int y){return s[x] < s[y];});
        _rep(i, 0, n - 2){
            int j = i; ll tot = lcp(p[i] + 1, 2) + 1;
            while(j < n - 2 && s[p[j + 1]] == s[p[i]]) j++, tot += lcp(p[j] + 1, 2) + 1;
            tot += n;
            if(s[p[i]] != s[1])
                res[1] = max(res[1], tot);
        }
        /*work 2~n*/
        ll sum = 0, cnt = 0;
        _rep(i, 2, n){
            if(r[i] >= i) sum += r[i], cnt++, h[r[i]].pb(i);
            pre[i] = sum - cnt * (i - 1);
            for(auto &j : h[i]) sum -= i, cnt--;
            h[i].clear();
        }
        sum = cnt = 0;
        _req(i, n, 2){
            if(z[i] < i) h[z[i]].pb(i);
            for(auto &j : h[i]) sum += j, cnt++;
            suf[i] = sum - cnt * (i - 1);
            h[i].clear();
        }
        _rep(i, 2, n){
            v[r[i]].pb({nxt[i], f[i]});
            // if(z[i] < i - 1 && i + z[i] <= n) v[z[i]].pb({s[i + z[i]], g[i]});
        }
        _req(i, n, 2){
            ll cur = ans;
            cur -= pre[i];
            cur -= suf[i];
            // _rep(j, 2, n) if(r[j] >= i) cur -= r[j] - i + 1;
            // _rep(j, i + 1, n) if(z[j] >= i) cur -= z[j] - i + 1;
            sort(v[i - 1].begin(), v[i - 1].end());
            int len = v[i - 1].size();
            res[i] = max(res[i], cur);
            _rep(j, 0, len - 1){
                int k = j; ll tot = v[i - 1][j].se;
                while(k < len - 1 && v[i - 1][k + 1].fi == v[i - 1][j].fi) k++, tot += v[i - 1][k].se;
                if(v[i - 1][j].fi != s[i])
                    res[i] = max(res[i], cur + tot);
                j = k;
            }
            if(z[i] < i - 1 && i + z[i] <= n) v[z[i]].pb({s[i + z[i]], g[i]});
            // _rep(j, 1, n){
            //     if(s[i] == j) continue;
            //     ll tot = 0;
            //     _rep(k, 2, i) if(r[k] == i - 1 && nxt[k] == j) tot += f[k];
            //     _rep(k, i + 1, n) if(z[k] == i - 1 && s[k + z[k]] == j) tot += g[k];
            //     res[i] = max(res[i], cur + tot);
            // }
        }
        ll t = 0;
        _rep(i, 1, n){
            t += (res[i] ^ i);
            debug("%d\n", res[i]);
        }
        writeln(t);
        clr();
    }    
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 24044kb

input:

2
4
2 1 1 2
12
1 1 4 5 1 4 1 9 1 9 8 10

output:

15
217

result:

ok 2 lines

Test #2:

score: -100
Time Limit Exceeded

input:

10000
8
2 1 2 1 1 1 2 2
9
2 2 1 2 1 2 1 2 1
15
2 1 2 1 1 1 1 2 2 1 2 1 2 2 1
2
1 1
10
2 1 1 1 2 2 1 1 2 2
3
2 1 2
11
1 2 2 1 1 2 1 2 2 1 1
14
2 1 1 1 1 2 1 1 1 2 2 1 2 1
12
2 2 2 1 2 2 2 1 1 2 1 2
4
2 1 1 2
8
1 2 2 2 1 2 1 1
8
1 1 2 1 2 1 1 1
6
2 1 1 1 2 2
14
2 2 1 1 1 1 2 2 2 1 2 2 1 1
10
1 2 2 1 1...

output:

97
128
313
1
194
18
187
283
248
15
88
96
99
229
198
3
341
328
335
307
1
19
120
81
13
75
54
199
10
64
37
178
103
104
246
226
20
59
352
58
96
19
21
67
299
342
256
291
264
268
309
335
224
287
3
283
54
323
8
70
32
141
336
48
316
81
247
1
159
320
242
20
148
1
406
378
367
86
256
375
20
54
52
265
3
16
327
...

result: