QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#184379 | #7088. Square Graph | Dualqwq | WA | 31ms | 67200kb | C++14 | 4.5kb | 2023-09-20 18:09:20 | 2023-09-20 18:09:21 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
namespace FastIO {
#define iL (1 << 20)
char ibuf[iL],*iS = ibuf + iL,*iT = ibuf + iL;
#define gc() (iS == iT ? (iT = (iS = ibuf) + fread(ibuf,1,iL,stdin),iS == iT ? EOF : *iS++) : *iS++)
template<typename T>
inline void read(T &a) {
char ch;int sign = 0;
for(ch = gc();!isdigit(ch);ch = gc())
if(ch == '-') sign = 1;
a = ch & 15;
for(ch = gc();isdigit(ch);ch = gc())
a = (a << 3) + (a << 1) + (ch & 15);
if(sign) a = -a;
}
char Out[iL],*iter = Out;
#define flush() fwrite(Out,1,iter - Out,stdout),iter = Out
template<typename T>
inline void write(T x,char end = '\n') {
int c[40],l = 0;if(x < 0) *iter++ = '-',x = -x;
do c[++l] = x % 10,x /= 10; while(x);
while(l) *iter++ = c[l--] + '0';
*iter++ = end;flush();
}
#undef iL
#undef gc
#undef flush
}
using namespace FastIO;
const int N = 3e5 + 5,Lg = 20;
typedef long long ll;
int n;
int a[N],b[N],w[N];
int lg[N];
struct SA {
SA(){}
int v1[N],v2[N];
int sa[N],ton[N];
inline bool cmp(int *r,int i,int j,int k) { return r[i] == r[j] && r[i + k] == 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--)
For(i,1,n) sa[i] = v1[i] = v2[i] = 0;
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];
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 GetHeight(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];
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 *a,int n) {
Getsa(a,sa,n,n);
GetHeight(a,n);
for(int i = 1;i <= n;i++) 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 A,B;
struct BCJ {
int fa[N];
inline void init(int n) { for(int i = 1;i <= n;i++) fa[i] = i;}
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]);}
inline void Merge(int x,int y) { fa[find(x)] = find(y);}
inline int Same(int x,int y) { return find(x) == find(y);}
}S[Lg],S0;
long long ans;
inline void Union(int x,int y,int dep) { // [x,x + 2^{dep}) , [y,y + 2^{dep})
if(S[dep].Same(x,y)) return;
if(dep == 0) {
if(!S0.Same(x,y)) ans += w[y - x],S0.Merge(x,y);
return;
}
S[dep].Merge(x,y);
Union(x,y,dep - 1);
if(y + (1 << dep - 1) <= n) Union(x + (1 << dep - 1),y + (1 << dep - 1),dep - 1);
}
int srt[N];
inline void Work() {
read(n);
for(int i = 1;i <= n;i++) read(a[i]),b[n - i + 1] = a[i];
for(int i = 1;i <= n / 2;i++) read(w[i]),srt[i] = i;
A.init(a,n);B.init(b,n);
sort(srt + 1,srt + n / 2 + 1,[&](const int &x,const int &y) { return w[x] < w[y];});
S0.init(n);
for(int i = 0;i < Lg;i++) S[i].init(n);
lg[0] = -1;
for(int i = 1;i <= n;i++) lg[i] = lg[i >> 1] + 1;
ans = 0;
for(int _ = 1;_ <= n / 2;_++) {
int len = srt[_];
for(int i = len;i <= n;i += len) {
int l = i,r = i + len;
int L = n - (r - 1) + 1,R = n - (l - 1) + 1;
int lcp = A.LCP(l,r);lcp = min(lcp,len);
int lcs = B.LCP(L,R);lcs = min(lcs,len - 1);
// printf("find:%d,%d,%d,%d\n",l,r,lcp,lcs);
if(lcp + lcs >= len) {
int tlen = lcp + lcs - len + 1;
int cl = i - lcs,cr = cl + tlen - 1;
// printf("AddEdge:%d,%d,%d\n",cl,cr,len);
cr = cr + len - 1;
assert(cr <= n);
int k = lg[cr - cl + 1];
Union(cl,cl + len,k);
Union(cr - (1 << k) + 1,cr - (1 << k) + 1 + len,k);
}
}
}
write(ans);
}
int main() {
int T;read(T);
while(T--) Work();
return 0;
}
/*
1
41
1 1 2 1 1 2 1 1 2 2 2 1 1 1 2 2 1 2 1 1 2 1 2 2 1 1 1 1 1 2 2 1 1 1 1 2 2 2 1 1 2
37 81 33 27 88 64 13 12 39 94 90 76 5 94 6 10 87 91 7 48
*/
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 56692kb
input:
1 8 2 2 5 6 2 5 6 2 5 1 4 4
output:
21
result:
ok "21"
Test #2:
score: -100
Wrong Answer
time: 31ms
memory: 67200kb
input:
3000 41 1 1 2 1 1 2 1 1 2 2 2 1 1 1 2 2 1 2 1 1 2 1 2 2 1 1 1 1 1 2 2 1 1 1 1 2 2 2 1 1 2 37 81 33 27 88 64 13 12 39 94 90 76 5 94 6 10 87 91 7 48 43 2 2 2 2 1 2 2 1 1 1 2 1 1 2 1 1 2 2 1 1 1 1 1 2 2 2 1 2 2 2 1 2 1 1 2 2 1 1 2 1 2 1 1 55 29 4 81 8 90 1 95 94 70 5 3 64 67 70 60 39 59 39 29 99 47 1 2...
output:
1169 1527 1193 1065 739 394 3245 1196 2962 1399 3334 1952 1093 2577 901 83 1559 226 3055 2631 212 2804 1769 925 2652 2040 2106 3917 1608 517 532 1447 2712 1845 2797 628 2551 2637 210 471 3293 1362 1210 2021 1096 1490 2931 3200 4073 1641 1851 4823 864 1502 1674 698 2189 2144 1878 1053 566 337 1524 26...
result:
wrong answer 61st words differ - expected: '421', found: '566'