QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#184379#7088. Square GraphDualqwqWA 31ms67200kbC++144.5kb2023-09-20 18:09:202023-09-20 18:09:21

Judging History

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

  • [2023-09-20 18:09:21]
  • 评测
  • 测评结果:WA
  • 用时:31ms
  • 内存:67200kb
  • [2023-09-20 18:09:20]
  • 提交

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'