zoukankan      html  css  js  c++  java
  • LOJ6287

    题目链接

    题意:

    给出(n(n<=1e5))的一个排列{({p_i})}(_{i=1}^n),判断是否存在一个三元组((i,j,k))使得(p_i-p_j==p_j-p_k)

    题解:

    绝妙的题目
    考虑枚举中间点j
    开一颗权值线段树维护数x在j左侧是否出现过
    如果出现过记为1,反之为0
    设len为(p_j)最长能延伸的长度(即(min(n-p_j,p_j-1)))
    每次询问在线段树上查找以j为中心,len为半径(向左和向右)的一段哈希值(哈希的每一位就是如前所述的1/0)
    如果二者相等,那么满足条件的两个数在同一侧,不可行
    如此循环即可
    至于如何快速求出hash,见代码(要维护两种哈希:正的和反的)

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=3e5+5,base=3,mod=19930219;
    int n,a[N],pw[N];
    int hash_z[N<<2],hash_f[N<<2];
    inline int read()
    {
    	int s=0,w=1; char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())if(ch=='-')w=-1;
    	for(;isdigit(ch);ch=getchar())s=(s<<1)+(s<<3)+(ch^48);
    	return s*w;
    }
    inline void up(int rt,int l,int r)
    {
    	int mid=l+r>>1;
    	hash_z[rt]=(1ll*hash_z[rt<<1]*pw[r-mid]%mod+hash_z[rt<<1|1])%mod;
    	hash_f[rt]=(1ll*hash_f[rt<<1|1]*pw[mid-l+1]%mod+hash_f[rt<<1])%mod;
    }
    void update(int rt,int l,int r,int x)
    {
    	if(l==r){hash_z[rt]=hash_f[rt]=1;return;}
    	int mid=l+r>>1;
    	if(x<=mid)update(rt<<1,l,mid,x);
    	else update(rt<<1|1,mid+1,r,x);
    	up(rt,l,r);
    }
    int query(int rt,int l,int r,int x,int y,bool tp)
    {
    	if(l==x&&r==y)return tp?hash_f[rt]:hash_z[rt];
    	int mid=l+r>>1;
    	if(y<=mid)return query(rt<<1,l,mid,x,y,tp);
    	else if(x>mid) return query(rt<<1|1,mid+1,r,x,y,tp);
    	else
    	{
    		int L=query(rt<<1,l,mid,x,mid,tp),R=query(rt<<1|1,mid+1,r,mid+1,y,tp);
    		if(!tp)return (1ll*L*pw[y-mid]%mod+R)%mod;
    		else return (1ll*R*pw[mid-x+1]%mod+L)%mod;
    	}
    }
    int main()
    {
    	n=read();pw[0]=1;
    	for(int i=1;i<=n;++i)
    		a[i]=read(),pw[i]=pw[i-1]*base%mod;
    	update(1,1,n,a[1]);
    	for(int i=2;i<n;++i)
    	{
    		update(1,1,n,a[i]);
    		if(a[i]==1||a[i]==n)continue;
    		int len=min(a[i]-1,n-a[i]);
    		if(query(1,1,n,a[i]-len,a[i],0)!=query(1,1,n,a[i],a[i]+len,1))
    		{
    			puts("YES");
    			return 0;
    		}
    	}
    	puts("NO");
    	return 0;
    }
    
  • 相关阅读:
    安利一个_Java学习笔记总结
    九涯的第一次
    attrs 资源文件 自定义属性
    EditText
    ArrayList 数组 初始化方法
    HTTP Retrofit 网络传输
    画布Canvas 画笔Paint
    View控件跟随鼠标移动
    ViewPager和Fragment中的View的点击事件冲突
    圆形图片 ImageView
  • 原文地址:https://www.cnblogs.com/zmyzmy/p/13642117.html
Copyright © 2011-2022 走看看