QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#184352#7088. Square GraphDualqwqRE 0ms56812kbC++144.2kb2023-09-20 17:38:182023-09-20 17:38:19

Judging History

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

  • [2023-09-20 17:38:19]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:56812kb
  • [2023-09-20 17:38:18]
  • 提交

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] = a[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(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) {
		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);
	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);
			if(lcp + lcs >= len) {
				int tlen = lcp + lcs - len + 1;
				int cl = i - lcs,cr = cl + tlen - 1;
				cr = cr + len - 1;
				int k = lg[cr - cl + 1];
				// printf("AddEdge:%d,%d,%d\n",cl,cr,len);
				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;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 56812kb

input:

1
8
2 2 5 6 2 5 6 2
5 1 4 4

output:

21

result:

ok "21"

Test #2:

score: -100
Runtime Error

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:


result: