QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#617697#7780. Dark LaTeX vs. Light LaTeXricofxTL 1ms5968kbC++204.8kb2024-10-06 16:42:032024-10-06 16:42:03

Judging History

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

  • [2024-11-25 20:53:52]
  • hack成功,自动添加数据
  • (/hack/1258)
  • [2024-10-06 16:42:03]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:5968kb
  • [2024-10-06 16:42:03]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 5000 + 5;

int n, m;

char s[N], t[N];

struct Sa{
    char s[N << 1];
    int SA[N << 1], rk[N << 1], oldrk[N << 2], id[N << 1], key1[N << 1], cnt[N << 1];
    int height[N << 1], n, pre[N << 1];
    bool cmp(int x, int y,int w){
        return oldrk[x] == oldrk[y] && oldrk[x + w] == oldrk[y + w];
    }
    void getSA(){
        memset(cnt, 0, sizeof(cnt));
        memset(rk, 0, sizeof(rk));
        memset(pre, 0, sizeof(pre));
        n = strlen(s + 1);
        int m = 127;
        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 = n; i >= 1; --i) SA[cnt[rk[i]]--] = i;
        for(int len = 1, p;; len <<= 1, m = p){
            p = 0;
            for(int i = n; i > n - len; --i) id[++p] = i;
            for(int i = 1; i <= n; ++i)
                if(SA[i] > len) id[++p]  = SA[i] - len;
            memset(cnt, 0, sizeof(cnt));
            for(int i = 1; i <= n; ++i) ++cnt[key1[i] = rk[id[i]]];
            for(int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
            for(int i = n; i >= 1; --i) SA[cnt[key1[i]]--] = id[i];
            memcpy(oldrk + 1, rk + 1, n * sizeof(int));
            p = 0;
            for(int i = 1; i <= n; ++i)
                rk[SA[i]] = cmp(SA[i], SA[i - 1], len) ? p : ++p;
            if(p == n)break;
        }
    }
    void getHeight(int lim) {
        for(int i = 1, k = 0; i <= n; ++i){
            if(rk[i] == 0) continue;
            if(k) --k;
            while(s[i + k] == s[SA[rk[i] - 1] + k])++k;
            height[rk[i]] = k;
        }
        for(int i = 1; i <= n; ++i)
            if(SA[i] > lim) pre[i]++;
        for(int i = 1; i <= n; ++i)
            pre[i] += pre[i - 1];
    }
    int st[18][N << 1], lg[N << 1];
    void initST() {
        lg[1] = 0;
        for(int i = 2; i <= n; ++i) lg[i] = lg[i >> 1] + 1;
        for(int i = 1; i <= n; ++i) st[0][i] = height[i];
        for(int j = 1; j <= lg[n]; ++j)
            for(int i = 1; i <= n - (1 << j) + 1; ++i)
                st[j][i] = min(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
    }
    int RMQ(int x, int y){
        int t = lg[y - x + 1];
        return min(st[t][x], st[t][y - (1 << t) + 1]);
    }
    int LCP(int x,int y) {
        x = rk[x], y = rk[y];
        if(x > y) swap(x, y);
        return RMQ(x + 1, y);
    }

    int findL(int s,int len){
        if(height[rk[s]] < len)return 0;
        int l = 1, r = rk[s], p = rk[s];
        while(l < r){
            int mid = l + r >> 1;
            if(RMQ(mid + 1, p) >= len) r = mid;
            else l = mid + 1;
        }
        return pre[p] - pre[r - 1];
    }

    int findR(int s,int len) {
        if(height[rk[s] + 1] < len)return 0;
        int l = rk[s] + 1, r = n, p = rk[s];
        while(l < r){
            int mid = l + r + 1 >> 1;
            if(RMQ(p + 1, mid) >= len) l = mid;
            else r = mid - 1;
        }
        return pre[l]  - pre[p];
    }

    int getcnt(int s,int len){
        return findR(s, len) + findL(s, len);
    }

}p;

int c[N][N];
ll ans = 0;

void work(bool opt = false){
    p.getSA();
    p.getHeight(n + 1);
    p.initST();
    ll res = 0;
    for(int i = 1; i <= n; ++i)
        // for(int j = i; j <= n; ++j)
        for(int j = 1; j <= i; ++j)
            res += (c[i][j] = p.getcnt(j, i - j + 1));
    // for(int i = 1; i <= n; ++i,putchar('\n'))
    //     for(int j = 1; j <= n; ++j)
    //         printf("%d ",c[j][i]);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= i; ++j)
            c[i][j] += c[i][j - 1];
    for(int i = 1; i <= n; ++i){
        for(int j = i + 1; j <= n; ++j) {
            int len = j - i, lcp = min(p.LCP(i, j), len - 1);
            if(!lcp) continue;
            ans += c[j - 1][i + lcp] - c[j - 1][i];
        }
    }
    // printf("res = %d\n", ans);
    if(opt) ans += res;
}

void MAIN(){
    scanf("%s",s + 1); scanf("%s",t + 1);
    n = strlen(s + 1), m = strlen(t + 1);
    memcpy(p.s + 1, s + 1, sizeof(char) * n);
    p.s[n + 1] = '#';
    memcpy(p.s + n + 2, t + 1, sizeof(char) * m);
    work(true);
    reverse(s + 1, s + 1 + n);
    reverse(t + 1, t + 1 + m);
    swap(n, m);
    swap(s, t);
    memcpy(p.s + 1, s + 1, sizeof(char) * n);
    p.s[n + 1] = '#';
    memcpy(p.s + n + 2, t + 1, sizeof(char) * m);
    work();
    printf("%lld\n", ans);
    // printf("%s\n%s\n",s + 1, t + 1);
}

int main(){
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
    // cin >> T;
    while (T--)
        MAIN();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3996kb

input:

abab
ab

output:

8

result:

ok 1 number(s): "8"

Test #2:

score: 0
Accepted
time: 1ms
memory: 5904kb

input:

abab
abaaab

output:

29

result:

ok 1 number(s): "29"

Test #3:

score: 0
Accepted
time: 1ms
memory: 4160kb

input:

abcd
abcde

output:

10

result:

ok 1 number(s): "10"

Test #4:

score: 0
Accepted
time: 1ms
memory: 5968kb

input:

aaba
ba

output:

6

result:

ok 1 number(s): "6"

Test #5:

score: 0
Accepted
time: 1ms
memory: 4112kb

input:

babababaaabbaabababbbaabbbababbaaaaa
aaaabbaababbab

output:

1161

result:

ok 1 number(s): "1161"

Test #6:

score: -100
Time Limit Exceeded

input:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...

output:


result: