QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#189522#7506. StrCartesianucup-team1209WA 25ms60876kbC++208.2kb2023-09-27 16:23:322023-09-27 16:24:56

Judging History

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

  • [2023-09-27 16:24:56]
  • 评测
  • 测评结果:WA
  • 用时:25ms
  • 内存:60876kb
  • [2023-09-27 16:23:32]
  • 提交

answer

#include <bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
using pi = pair <int, int> ; 
using ll = long long; 
mt19937 rnd(1);
cs int N = 1e5 + 5; 

int n, m; 
string A; 
int p[N], len[N], skip[N];

namespace SA {
cs int N = 2e6 + 5; 
int sa[N], tmp[N << 1], rk[N << 1], y[N], n, m; 
int st[21][N];
void Sort() {
    static int c[N];
    for(int i = 0; i <= m; i++) c[i] = 0; 
    for(int i = 1; i <= n; i++) c[rk[i]] ++;
    for(int i = 1; i <= m; i++) c[i] += c[i - 1];
    for(int i = n; i; i--) sa[c[rk[y[i]]]--] = y[i];
}
void work(string a) {  
    n = a.length(), m = 128; 
    for(int i = 1; i <= n; i++) 
        rk[i] = a[i - 1], y[i] = i;
    Sort();
    for(int k = 1; k <= n; k <<= 1) {
        int ret = 0; 
        for(int i = n - k + 1; i <= n; i++) y[++ ret] = i; 
        for(int i = 1; i <= n; i++) if(sa[i] > k) y[++ ret] = sa[i] - k; 
        Sort();
        swap(rk, tmp);
        rk[sa[1]] = 1; 
        int num = 1; 
        for(int i = 2; i <= n; i++) {
            if(tmp[sa[i]] == tmp[sa[i - 1]] && tmp[sa[i] + k] == tmp[sa[i - 1] + k]) 
                rk[sa[i]] = num;
            else 
                rk[sa[i]] = ++ num;
        }
        m = num; 
    }
    
    int k = 0;
    for(int i = 1;i <= n; i++) {
        if(rk[i] == 1) continue; 
        int j = sa[rk[i] - 1]; if(k) k--;
        while(i + k <= n && j + k <= n && a[i + k - 1] == a[j + k - 1]) k++;
        st[0][rk[i]] = k; 
    }
    for(int i = 1; i < 21; 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))]);
}
int lcp(int x, int y) {
    if(x == y) return 1e6; 
    assert(x > 0 && y > 0);
    // cout << "FFFF " << x << ' ' << y << endl;
    x = rk[x], y = rk[y];
    // cout << "FFFF " << x << ' ' << y << endl;
    if(x > y) swap(x, y); ++ x; 
    int z = __lg(y - x + 1);
    return min(st[z][x], st[z][y - (1 << z) + 1]);
}
}
int check(int a, int b) {
    // cout << a << " " << b << ' ' << p[a] << ' ' << p[b] <<endl;
    int l = SA :: lcp(p[a], p[b]);
    l = min({l, len[a], len[b]}); 
    if(l < len[a] && l < len[b]) return SA :: rk[p[a]] < SA :: rk[p[b]];
    return len[a] < len[b];
}
int check2(int a, int b, int s, int f) {

    assert(a != s);
    
    bool o = (len[a] + len[b] < len[s] + len[f]) || (len[a] + len[b] == len[s] + len[f] && a < s);
    int l = SA :: lcp(p[a], p[s]);
    l = min({l, len[a], len[s]});
    
    if(l < len[a] || l < len[s]) 
        return SA :: rk[p[a]] < SA :: rk[p[s]];


    if(len[a] + len[b] <= len[s]) {
        int res = len[s] - len[a];
        l = SA :: lcp (p[s] + len[a], p[b]);
        if(l < len[b] && l < res) return SA :: rk[p[b]] < SA :: rk[p[s] + len[a]];
        return 1; 
    }

    if(len[s] + len[f] <= len[a]) {
        int res = len[a] - len[s];
        l = SA :: lcp(p[a] + len[s], p[f]);
        if(l < res && l < len[f]) return SA :: rk[p[a] + len[s]] < SA :: rk[p[f]];
        return 0; 
    }

    
    if(len[a] < len[s]) {
        int res = len[s] - len[a];
        l = SA :: lcp(p[s] + len[a], p[b]);
        if(l < res && l < len[b]) return SA :: rk[p[b]] < SA :: rk[p[s] + len[a]];

        l = SA :: lcp(p[b] + res, p[f]);
        if(l < len[b] - res && l < len[f]) return SA :: rk[p[b] + res] < SA :: rk[p[f]];
        return o;
    }
    // len[a] >= len[s] 
    
    int res = len[a] - len[s];
    l = SA :: lcp(p[a] + len[s], p[f]);
    if(l < res && l < len[f]) return SA :: rk[p[a] + len[s]] < SA :: rk[p[f]];
    l = SA :: lcp(p[b], p[f] + res);
    if(l < len[f] - res && l < len[b]) return SA :: rk[p[b]] < SA :: rk[p[f] + res];
    return o;
}

ll calc(int s, int f, vector <int> & l, vector <int> & r, cs vector <int> & pl, cs vector <int> & pr, int & k) {
    vector <int> mid(n + 1);
    ll ans = 0; 
    assert(1 <= s && s <= n);
    assert(1 <= f && f <= m);
    // cout << "CALC " << s <<' ' << f << endl;
    for(int i = 1;i <= n; i++) 
    if(l[i] <= r[i]) {
        if(i == s) {
            mid[i] = f; 
            continue; 
        }
        int L = l[i], R = r[i];
        while(L < R) {
            int mi = (L + R + 1) >> 1;
            if(check2(pl[i], pr[mi] + n, pl[s], pr[f] + n)) {
                L = mi; 
            }
            else {
                R = mi - 1; 
            }
        }
        if(check2(pl[i], pr[L] + n, pl[s], pr[f] + n)) mid[i] = L; 
        else mid[i] = L - 1; 
    }
    for(int i = 1; i <= n; i++)
    if(l[i] <= r[i]) ans += mid[i] - l[i] + 1; 
    // cout << "Calc " << s << ' ' << f << ' ' << ans << ' ' << k << endl;
    if(ans <= k) {
        k -= ans; 
        for(int i = 1; i <= n; i++)
            if(l[i] <= r[i]) l[i] = mid[i] + 1;
    }
    else {
        for(int i = 1; i <= n; i++)
            if(l[i] <= r[i]) r[i] = mid[i]; 
    }
    for(int i = 1; i <= n; i++) {
        assert(l[i] <= r[i] || r[i] == l[i] - 1);
    //    cout << l[i] << ' ' << mid[i] << ' ' << r[i] << endl;
    }
    return ans; 
}

int main() {
    #ifdef zqj
    freopen("1.in","r",stdin);
    #endif
    ios::sync_with_stdio(false),cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        string a;
        cin >> a; 
        int l = a.length();
        len[i] = l;
        A += a; 
    }
    p[0] = 1; 
    for(int i = 1; i <= n; i++) 
        p[i] = p[i - 1] + len[i - 1];
    for(int i = 1; i <= m; i++) {
        string b; 
        cin >> b; 
        int l = b.length();
        len[i + n] = l; 
        A += b; 
    }
    for(int i = n + 1; i <= n + m; i++) 
        p[i] = p[i - 1] + len[i - 1];
    SA :: work(A);
    
    vector <int> pl(n + 1), pr(m + 1);
    for(int i = 1; i <= n; i++) pl[i] = i;
    for(int i = 1; i <= m; i++) pr[i] = i;
    sort(pl.begin() + 1, pl.end(), 
    [](cs int & x, cs int & y) {
        return check(x, y);
    });
    sort(pr.begin() + 1, pr.end(),
    [](cs int & x, cs int & y) {
        return check(x + n, y + n);
    });

    // for(int i =1 ; i <= n; i++) cout << pl[i] << ' '; cout << endl;
    // for(int i =1 ; i <= m; i++) cout << pr[i] << ' '; cout << endl;

    // for(int i = 1; i <= n + m; i++) cout << p[i] << ' '; cout << endl;
    // int le = A.length();
    // // for(int i = 1; i <= le; i++) cout << SA :: rk[i] << ' '; cout << endl;
    // for(int i = 1, x = 0; i <= le; i++) {
    //     if(x < m && check(x + m, SA :: rk[p[pr[x + 1] + n]] == i) ++ x; 
    //     skip[i] = x; 
    //     // cout << "FFF " << i <<" " << x << ' ' << pr[x] << ' ' << p[pr[x] + n] << endl;
    // }
    // return 0; 

    int q; 
    cin >> q; 
    for(int t = 0; t < q; t++) {
        vector <int> l(n + 1), r(n + 1);
        for(int i = 1; i <= n; i++) r[i] = m, l[i] = 1; 
        int k; 
        cin >> k; 
        int anss = 0, ansf = 0; 
        // cout << "query ------------------------------------ " << k << endl;
        for(int i = 0; i < 50; ++i) {
            int siz = 0;
            for(int i = 1; i <= n; i++)
                if(l[i] <= r[i]) siz += r[i] - l[i] + 1; 
            int t = rnd() % siz + 1; 
            int s = 0, f = 0; 
            // for(int i = 1; i <= n; i++) cout << l[i] << ' ' << r[i] << endl;
            //cout << "asfasasdfafsfasafsd--------------------- " << siz << ' ' << t << ' ' << s << ' ' << f << endl;
            for(int i = 1; i <= n; i++) if(l[i] <= r[i]) {
                // cout << i << ' ' << t << ' ' << r[i] - l[i] + 1 <<  endl;
                if(t <= r[i] - l[i] + 1) {
                    s = i, f = l[i] + t - 1; 
                    break;
                }
                t -= r[i] - l[i] + 1; 
            }
            anss = s, ansf = f; 
            if(siz == 1) {
                break;
            }
            //cout << "asfasasdfafsfasafsd--------------------- " << siz << ' ' << t << ' ' << s << ' ' << f << endl;
            ll num = calc(s, f, l, r, pl, pr, k);
            // cout << s << ' ' << f << ' ' << num << ' ' << k <<  endl;
            // for(int i = 1; i <= n; i++) cout << l[i] << ' ' << r[i] << endl;
            if(k == 0) break;
            // exit(0);
        }
        cout << anss << ' ' << ansf << '\n';
        // exit(0);
    }
    return 0; 
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 7ms
memory: 46460kb

input:

2 3
a
ab
a
aa
ba
2
3
4

output:

1 3
2 1

result:

ok Correct Answer

Test #2:

score: -100
Wrong Answer
time: 25ms
memory: 60876kb

input:

27 28
ptdtljwzjbyctrjetnossaiogcfce
kmuwnsxjenpjybcwrecoqddbltzvnkzzrxvne
lsbqkpbgihqahpotzrnggqrompohf
ixonxrpixmurqgdtedhavpawmddfw
ruhqnxhvucv
fvarlrf
uyxxjzjf
tlzrxaykw
kldatopsv
fywmszxti
yraazxvbfebdhekphdrqhvpmferaghezebm
dovtqdvdd
waohxsasgl
biakvxhqx
aeyzaqum
repmbqtrvwd
dvqojkduc
sjxapwnyz...

output:

12 8
14 24
10 19
14 19
20 1
27 13
24 27
11 8
19 22
6 11
20 21
17 28
7 20
25 6
6 10
16 4
17 6
12 26
8 21
15 18
8 15
18 15
21 6
16 22
3 27
5 4
23 9
3 9
12 17
8 10
4 23
11 27
23 17
18 24
20 20
18 8
7 16
8 10
5 7
17 28
6 28
3 15
21 7
1 24
8 1
13 24
10 7
22 8
6 12
20 8
6 22
4 13
16 13
11 12
14 17
1 14
5 ...

result:

wrong answer The 1-th query is wrong