关于本题的数据(不是关于数据规模
查看原帖
关于本题的数据(不是关于数据规模
67817
MuYC楼主2021/2/4 17:24

RT,本人用NTT + 分块判断是否存在等差子序列。

按理来说,时间复杂度是 O(mnm*n + n/mnlognn/m * nlogn)的,想着应该可以过的,但是却T了,于是我大胆的把NTT注释掉了后看到底是什么导致我超时,但是它过了!!!!!我直接大呼好家伙

敢问这数据到底是有多令人害怕.......

(mm 是分块的大小)

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e4 + 50;
#define int long long
const int Mod = 998244353;
int A[MAXN];
int Lef[MAXN],Rig[MAXN];
int JL[MAXN],JR[MAXN];
int n;
int L[1005],R[1050],num = 0,rev[MAXN];
int pre[MAXN],nxt[MAXN];
int lim = 1, l = 0,m;
long long Ans = 0;

inline int read() {
	int x = 0 , flag = 1;
	char ch = getchar();
	for( ; ch > '9' || ch < '0' ; ch = getchar()) if(ch == '-') flag = -1;
	for( ; ch >= '0' && ch <= '9' ; ch = getchar()) x = (x << 3) + (x << 1) + ch - '0';
	return x * flag;
}

int quickpower(int x,int y) {
	int ans = 1 , op = x;
	while(y) {
		if(y & 1) ans *= op , ans %= Mod;
		op *= op , op %= Mod;
		y >>= 1;
	}
	return ans;
}

void NTT(int * a , int type) {
	for(int i = 0 ; i < lim ; i ++)
		if(i < rev[i]) swap(a[i],a[rev[i]]);
	for(int mid = 1 ; mid < lim ; mid <<= 1) {
		int gn = quickpower(3 , (Mod - 1) / (mid << 1));
		for(int i = 0 ; i < lim ; i += (mid << 1)) {
			int g = 1;
			for(int j = 0 ; j < mid ; j ++ , g = (g * gn) % Mod) {
				int x = a[i + j] , y = a[i + j + mid] * g % Mod;
				a[i + j] = (x + y) % Mod;
				a[i + j + mid] = (x - y + Mod) % Mod;
			}
		}
	}
	if(type == 1) return ;
	reverse(a + 1, a + lim);
	int inv = quickpower(lim , Mod - 2);
	for(int i = 0 ; i < lim ; i ++) a[i] *= inv , a[i] %= Mod;
	return ;
}

void deal(int x) {
	for(int i = L[x] ; i <= R[x] ; i ++) Rig[A[i]] --;
	for(int i = L[x] ; i <= R[x] ; i ++) {
		for(int j = i + 1 ; j <= R[x] ; j ++) {
			if(A[j] < A[i] * 2) {
				Ans += pre[A[i] - (A[j] - A[i])];
				Ans += Lef[A[i] - (A[j] - A[i])];
			}
			if(A[j] * 2 > A[i])
			Ans += Rig[A[j] + (A[j] - A[i])];
		}
		pre[A[i]] ++;
	}
	for(int i = 0 ; i <= m ; i ++) JL[i] = Lef[i];
	for(int i = 0 ; i <= m ; i ++) JR[i] = Rig[i];
	for(int i = m + 1; i < lim ; i ++) JL[i] = JR[i] = 0;
	//NTT(JL , 1 ) ; NTT( JR , 1 );
	for(int i = 0 ; i < lim; i ++) JL[i] *= JR[i] , JL[i] %= Mod;
	//NTT( JL , - 1);
	for(int i = L[x] ; i <= R[x]; i ++) 
	Ans += JL[2 * A[i]], pre[A[i]] = 0,Lef[A[i]] ++;
	return ;
}

signed main() {
	
	int Q = read();
	while(Q --) {
		n = read();
		memset(JL,0,sizeof(JL)); memset(Rig,0,sizeof(Rig));
		memset(JR,0,sizeof(JR)); memset(Lef,0,sizeof(Lef)); 
		lim = 1 , l = 0;
		m = n; num = 0; Ans = 0;
		for(int i = 1 ; i <= n ; i ++) A[i] = read() , Rig[A[i]] ++;
		int block = 200;//块的大小
		while(R[num] != n) {
			num ++;
			L[num] = R[num - 1] + 1;
			R[num] = min(num * block , n);
		}
		for( ; lim <= m * 2 ; lim <<= 1) l ++;
		for(int i = 0 ; i <= lim ; i ++) 
		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (l - 1));
		for(int i = 1 ; i <= num ; i ++) deal(i);
		if(Ans != 0)cout << "Y" << endl;
		else cout << "N" << endl;
	}
	return 0;
}

我直接好家伙。。。

2021/2/4 17:24
加载中...