Codeforces452F Permutation

版权声明:写得不好,转载请通知一声,还请注明出处,感激不尽 https://blog.csdn.net/As_A_Kid/article/details/83652093

Problem

Codeforces

给你一个长度为 n ( n 3 1 0 5 ) n(n\leq 3*10^5) 的排列,问你存不存在 i < j < k i<j<k 使得 a j a i = a k a i a_j-a_i=a_k-a_i

Solution

一道很有意思的题目。。我做的时候思路从fft到线段树再到bitset到分治再到构造,反正就是搞来搞去不可做。。

我们考虑枚举 j j ,如果存在 i < j < k i<j<k 满足要求的话,就说明存在一个 x x ,使得 a j x a_j-x a j + x a_j+x 在前j个位置中的存在状态不同,如果完全一致就说明不存在。把存在状态表示成一个01串,就相当于询问串 [ a j p , a j ) [a_j-p,a_j) 和串 ( a j , a j + p ] (a_j,a_j+p] 是不是对称的,那翻转其中一个串再匹配。那么算法的瓶颈就在于如何快速的判断两个01串相同,用权值线段树维护hash值。

时间复杂度 O ( n log n ) O(n\log n)

Code

#include <algorithm>
#include <cstdio>
#define rg register
#define pushup(rt) a[rt]=a[rt<<1]+a[rt<<1|1],b[rt]=b[rt<<1|1]+b[rt<<1]
using namespace std;
typedef long long ll;
const int maxn=300010,base=7,mod=998244353;
template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> inline void read(Tp &x)
{
    x=0;int f=0;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=1,ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    if(f) x=-x;
}
int n,x,p,pw[maxn];
inline int pls(int x,int y){return x+y>=mod?x+y-mod:x+y;}
struct data{
	int val,len;
	data (const int _val=0,const int _len=0){val=_val;len=_len;}
	data operator + (const data &b)const
	{
		return data(pls(((ll)val*pw[b.len]%mod),b.val),len+b.len);
	}
}ta,tb,a[maxn<<2],b[maxn<<2];
void build(int l,int r,int rt)
{
	if(l==r)
	{
		a[rt]=b[rt]=data(0,1);
		return ;
	}
	int m=(l+r)>>1;
	build(l,m,rt<<1);build(m+1,r,rt<<1|1);
	pushup(rt);
}
void update(int l,int r,int pos,int rt)//insert
{
	if(l==r){a[rt]=b[rt]=data(1,1);return ;}
	int m=(l+r)>>1;
	if(pos<=m) update(l,m,pos,rt<<1);
	else update(m+1,r,pos,rt<<1|1);
	pushup(rt);
}
data qa(int l,int r,int L,int R,int rt)
{
	if(L<=l&&r<=R) return a[rt];
	int m=(l+r)>>1;data res;
	if(L<=m) res=res+qa(l,m,L,R,rt<<1);
	if(m<R) res=res+qa(m+1,r,L,R,rt<<1|1);
	return res;
}
data qb(int l,int r,int L,int R,int rt)
{
	if(L<=l&&r<=R) return b[rt];
	int m=(l+r)>>1;data res;
	if(m<R) res=res+qb(m+1,r,L,R,rt<<1|1);
	if(L<=m) res=res+qb(l,m,L,R,rt<<1);
	return res;
}
int main()
{
	#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	read(n);
	pw[0]=1;
	for(rg int i=1;i<=n;i++) pw[i]=(ll)pw[i-1]*base%mod;
	build(1,n,1);
	for(rg int i=1;i<=n;i++)
	{
		read(x);
		update(1,n,x,1);
		p=min(x-1,n-x);
		if(p<=0) continue;
		ta=qa(1,n,x-p,x-1,1);
		tb=qb(1,n,x+1,x+p,1);
		if(ta.val!=tb.val){puts("YES");return 0;}
	}
	puts("NO");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/As_A_Kid/article/details/83652093