QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#185748 | #4806. Suffix Sort | Dualqwq | WA | 453ms | 110240kb | C++14 | 4.5kb | 2023-09-22 16:06:54 | 2023-09-22 16:06:55 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5,M = 26;
int n;
char s[N];
int apr[N][M],srtch[N][M],chrk[N][M];
struct SA {
static const int N = 4e5 + 5,Lg = 19;
int sa[N],ton[N];
int v1[N],v2[N];
int n;
inline bool cmp(int *r,int i,int j,int k) {
return r[i] == r[j] && (i + k > n ? 0 : r[i + k]) == (j + k > n ? 0 : r[j + k]);
}
inline void Getsa(int *s,int *sa,int n,int m) {
#define For(i,a,b) for(int i = (a);i <= (b);i++)
#define Rof(i,a,b) for(int i = (a);i >= (b);i--)
int *x = v1,*y = v2,*t;
For(i,1,m) ton[i] = 0;
For(i,1,n) ton[x[i] = s[i]]++;
For(i,1,m) ton[i] += ton[i - 1];
Rof(i,n,1) sa[ton[x[i]]--] = i;
for(int j = 1,p;j <= n;j *= 2,m = p) {
p = 0;
For(i,n - j + 1,n) y[++p] = i;
For(i,1,n) if(sa[i] > j) y[++p] = sa[i] - j;
For(i,1,m) ton[i] = 0;
For(i,1,n) ton[x[i]]++;
For(i,1,m) ton[i] += ton[i - 1];
Rof(i,n,1) sa[ton[x[y[i]]]--] = y[i],y[i] = 0;
t = x;x = y;y = t;p = 1;x[sa[1]] = 1;
For(i,2,n) x[sa[i]] = cmp(y,sa[i - 1],sa[i],j) ? p : (++p);
if(p >= n) break;
}
#undef For
#undef Rof
}
int rk[N],height[N];
inline void Gethi(int *s,int n) {
for(int i = 1;i <= n;i++) rk[sa[i]] = i;
for(int i = 1,j = 0;i <= n;i++) {
if(j) --j;
if(rk[i] != 1)
while(i + j <= n && sa[rk[i] - 1] + j <= n && s[i + j] == s[sa[rk[i] - 1] + j])
++j;
height[rk[i]] = j;
}
}
int ST[Lg][N],lg[N];
inline int LCP(int l,int r) {
if(l <= 1 || r <= 1 || l > n || r > n) return 0;
l = rk[l];r = rk[r];
if(l > r) swap(l,r);
int k = lg[r - (l++)];
return min(ST[k][l],ST[k][r-(1<<k)+1]);
}
inline void init(int *s,int _n) {
n = _n;
Getsa(s,sa,n,n + M);
Gethi(s,n);
lg[0] = -1;
for(int i = 1;i <= n;i++) lg[i] = lg[i >> 1] + 1,ST[0][i] = height[i];
for(int j = 1;j < Lg;j++)
for(int i = 1;i + (1 << j) - 1 <= n;i++)
ST[j][i] = min(ST[j - 1][i],ST[j - 1][i + (1 << j - 1)]);
}
};
SA S;
vector<int> Pos[M];
int bel[N],id[N];
int difs[N]; // 差分数组拼起来的串
int lst[N];
inline int Rlcp(int x,int y) {
int res = 1e9;
for(int i = 0;i < M;i++) {
int c1 = srtch[x][i],c2 = srtch[y][i]; // 排名第 i 的字符
int p1 = apr[x][c1],p2 = apr[y][c2];
if(p1 > n && p2 > n) continue;
if(p1 <= n && p2 > n) { res = min(res,p1 - x);continue;}
if(p1 > n && p2 <= n) { res = min(res,p2 - y);continue;}
if(p1 - x != p2 - y) { res = min(res,min(p1 - x,p2 - y));continue;}
int p3 = apr[p1 + 1][c1],p4 = apr[p2 + 1][c2];
// printf("c,P:%d,%d,%d,%d,%d,%d\n",c1,c2,p1,p2,p3,p4);
if(p3 > n && p4 > n) continue;
if(p3 > n && p4 <= n) { res = min(res,p4 - y);continue;}
if(p3 <= n && p4 > n) { res = min(res,p3 - x);continue;}
int b1 = bel[apr[p1 + 1][c1]],b2 = bel[apr[p2 + 1][c2]];
// printf("b1,b2:%d,%d\n",b1,b2);
int tlen = S.LCP(b1,b2);
// printf("i1,i2:%d,%d,%d\n",tlen,id[p3] + tlen,id[p4] + tlen);
int t1 = id[p3] + tlen,t2 = id[p4] + tlen;
int pn1 = (t1 >= Pos[c1].size() ? n + 1 : Pos[c1][t1]);
int pn2 = (t2 >= Pos[c2].size() ? n + 1 : Pos[c2][t2]);
res = min(res,min(pn1 - x,pn2 - y));
}
// printf("Rlcp:%d,%d,%d\n",x,y,res);
return res;
}
inline bool Cmp(int x,int y) {
if(x == y) return false;
int tlen = Rlcp(x,y);
assert(x + tlen - 1 <= n);
assert(y + tlen - 1 <= n);
if(x + tlen - 1 == n) return true;
if(y + tlen - 1 == n) return false;
return chrk[x][s[x + tlen] - 'a'] < chrk[y][s[y + tlen] - 'a'];
}
int Ans[N];
int main() {
cin >> n;
cin >> (s + 1);
for(int i = 0;i < M;i++) apr[n + 1][i] = n + 1;
for(int i = n;i >= 1;i--) {
for(int j = 0;j < M;j++)
apr[i][j] = apr[i + 1][j];
apr[i][s[i] - 'a'] = i;
}
for(int i = 1;i <= n;i++) {
id[i] = Pos[s[i] - 'a'].size();
if(!id[i]) lst[i] = 0;
else lst[i] = Pos[s[i] - 'a'].back();
Pos[s[i] - 'a'].push_back(i);
}
int tot = 0;
for(int i = 0;i < M;i++) {
for(auto j : Pos[i])
++tot,bel[j] = tot,difs[tot] = j - lst[j];
difs[++tot] = n + 1 + i;
}
for(int i = 1;i <= n;i++) {
for(int j = 0;j < M;j++) srtch[i][j] = j;
sort(srtch[i],srtch[i] + M,[&](const int &x,const int &y) { return apr[i][x] < apr[i][y];});
for(int j = 0;j < M;j++)
chrk[i][srtch[i][j]] = j;
// printf("srtch[%d]:\n",i);
// for(int j = 0;j < M;j++) printf("%d ",srtch[i][j]);printf("\n");
}
S.init(difs,tot);
// cout << "LCP(3,2): " << Rlcp(3,2) << endl;
for(int i = 1;i <= n;i++) Ans[i] = i;
sort(Ans + 1,Ans + n + 1,Cmp);
for(int i = 1;i <= n;i++) printf("%d ",Ans[i]);printf("\n");
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 32520kb
input:
6 aadead
output:
6 1 5 4 3 2
result:
ok single line: '6 1 5 4 3 2 '
Test #2:
score: -100
Wrong Answer
time: 453ms
memory: 110240kb
input:
200000 baabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaaba...
output:
200000 199998 199995 199992 199989 199986 199983 199980 199977 199974 199971 199968 199965 199962 199959 199956 199953 199950 199947 199944 199941 199938 199935 199932 199929 199926 199923 199920 199917 199914 199911 199908 199905 199902 199899 199896 199893 199890 199887 199884 199881 199878 199875...
result:
wrong answer 1st lines differ - expected: '200000 199998 199995 199992 19... 99991 99994 99997 100000 99999', found: '200000 199998 199995 199992 19...99991 99994 99997 100000 99999 '