QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#189765#7506. StrCartesianucup-team1209TL 7292ms225264kbC++147.0kb2023-09-27 21:11:222023-09-27 21:11:23

Judging History

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

  • [2023-09-27 21:11:23]
  • 评测
  • 测评结果:TL
  • 用时:7292ms
  • 内存:225264kb
  • [2023-09-27 21:11:22]
  • 提交

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_64 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;
        }
        if(num == n) break;
        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; 
    x = rk[x], y = rk[y];
    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) {
    int l = SA :: lcp(p[a], p[b]);
    if(l < len[a] && l < len[b]) return SA :: rk[p[a]] < SA :: rk[p[b]];
    return len[a] < len[b] || (len[a] == len[b] && a < b);
}
vector <string> aa, bb; 
int check2(int a, int b, int s, int f) {
    // string c = aa[a] + bb[s];
    // string d = aa[s] + bb[f];
    // return c < d || (c == d && a < s);
    if(a == s) return check(b, f);
    
    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]);
    
    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, ll & k) {
    vector <int> mid(n + 1);
    ll ans = 0; 
    assert(1 <= s && s <= n);
    assert(1 <= f && f <= m);
    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];
        if(check2(pl[i], pr[R] + n, pl[s], pr[f] + n)) {
            mid[i] = R; 
            continue; 
        }
        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; 
    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);
    }
    return ans; 
}

int main() {
    #ifdef zqj
    freopen("3.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);
    });

    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; 
        ll k; 
        cin >> k; 
        int anss = 0, ansf = 0; 
        while(1) {
            ll siz = 0;
            for(int i = 1; i <= n; i++)
                if(l[i] <= r[i]) siz += r[i] - l[i] + 1; 
            ll t = rnd() % siz + 1; 
            int s = 0, f = 0; 
            for(int i = 1; i <= n; i++) if(l[i] <= r[i]) {
                if(t <= r[i] - l[i] + 1) {
                    s = i, f = l[i] + t - 1; 
                    break;
                }
                t -= r[i] - l[i] + 1; 
            }
            anss = pl[s], ansf = pr[f]; 
            if(siz == 1) {
                break;
            }
            ll num = calc(s, f, l, r, pl, pr, k);
            // cout << k << ' ' << num << ' ' << pl[s] << ' ' << pr[f] <<endl;
            if(k == 0) break;
        }
        cout << anss << ' ' << ansf << '\n';
        // cout<<aa[anss]<<endl<<bb[ansf]<<endl<<aa[anss]<<endl<<bb[19018]<<endl;
    }
    return 0; 
}

详细

Test #1:

score: 100
Accepted
time: 4ms
memory: 48544kb

input:

2 3
a
ab
a
aa
ba
2
3
4

output:

1 3
2 1

result:

ok Correct Answer

Test #2:

score: 0
Accepted
time: 13ms
memory: 60912kb

input:

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

output:

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

result:

ok Correct Answer

Test #3:

score: 0
Accepted
time: 7292ms
memory: 225264kb

input:

21673 22789
osjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwnyzosjxapwnyaosjxapwn...

output:

11748 7566
13026 16461
9916 11268
12937 6138
20884 12212
310 19018
14665 17118
7698 15274
18832 22061
7551 10949
12970 7192
1098 9710
19691 12422
5351 11239
14696 2061
2889 12319
8909 10800
6739 1691
19504 5705
599 16293
2991 6114
20067 16922
11544 17617
7562 4195
7364 20824
19750 22736
15334 22205
...

result:

ok Correct Answer

Test #4:

score: -100
Time Limit Exceeded

input:

42793 43577
osjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjyosjxosjy...

output:

478 23079
19578 5700
32327 37245
23174 34890
8775 43551
33235 7846
40699 41435
24607 32335
10681 5081
40664 38308
4711 11678
31506 13791
13592 7796
9099 15409
35 36153
12575 30943
1418 37944
18258 11644
4315 19248
29431 9382
9938 30089
16317 36775
25241 10476
27724 29981
33560 26458
311 26256
24402 ...

result: