QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#189522 | #7506. StrCartesian | ucup-team1209 | WA | 25ms | 60876kb | C++20 | 8.2kb | 2023-09-27 16:23:32 | 2023-09-27 16:24:56 |
Judging History
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