QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#189594 | #7506. StrCartesian | ucup-team1209 | WA | 7048ms | 228924kb | C++20 | 7.8kb | 2023-09-27 17:51:16 | 2023-09-27 17:51:51 |
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_64 rnd(time(0));
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) {
// 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] || (len[a] == len[b] && a > b);
}
int check2(int a, int b, int s, int f) {
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("2.in","r",stdin);
#endif
ios::sync_with_stdio(false),cin.tie(0);
vector <string> aa, bb;
aa.pb("");
bb.pb("");
cin >> n >> m;
for(int i = 1; i <= n; i++) {
string a;
cin >> a;
int l = a.length();
len[i] = l;
A += a;
aa.pb(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;
bb.pb(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);
});
// vector <pi> c;
// for(int i =1;i<=n;i++)for(int j=1;j<=m;j++)c.pb({i,j});
// sort(c.begin(), c.end(), [](cs pi &x, cs pi &y) {
// return check2(x.first, x.second +n, y.first, y.second +n);
// });
// for(auto [x, y] : c) cout<<x << ' ' << y <<endl;
// 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;
ll k;
cin >> k;
int anss = 0, ansf = 0;
for(int i = 0; i < 50; ++i) {
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);
if(k == 0) break;
}
cout << anss << ' ' << ansf << '\n';
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 48660kb
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: 7ms
memory: 61020kb
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: -100
Wrong Answer
time: 7048ms
memory: 228924kb
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 4223 8909 10800 6739 1691 19504 5705 599 16293 2991 6114 20067 12085 11544 17617 7562 4195 7364 15726 19750 22736 15334 22205 1...
result:
wrong answer The 16-th query is wrong