zoukankan      html  css  js  c++  java
  • 题解 P2757 【[国家集训队]等差子序列】

    Link

    P2757 [国家集训队]等差子序列

    Solve

    先转化一下题意,对于一个(a[i])我们判断如果存在一个(a[i]+k)(a[i]-k)(a[i])的异侧,那么就存在一个解,输出(yes),如果对于每个(a[i])都不存在,就输出(no)

    如何判断是否存在(a[i]+k)(a[i]-k)的位置,我们想到了回文,处理每个(a[i])时,我们把(a[i])这个位置打上(1),如果此时的序列不是以(a[i])为中心的回文,那么肯定有一个对应的(a[i]+k)或者(a[i]-k)(a[i])后面,就存在解了,如果是回文,那么对于这个(a[i])每一个k,(a[i]+k)(a[i]-k)都在(a[i])同侧了。

    如何维护回文,很容易的想到线段树+哈希,一个回文串,正着哈希和反过来哈希的结果是一样的,我们就建两棵线段树,一棵表示正着哈希,一棵表示反着哈希,反着哈希的树统计时就把左儿子和右儿子交换就好了,相当于把线段树做了一次对称(这么说也不够严谨,感性理解一下就好了)。

    多组数据注意一下细节

    Code

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3e5+5,TT=1e9+7,bas=27;
    typedef long long LL;
    int N,a[maxn],T,flg;
    LL pw[maxn];
    struct node{
    	LL val;
    	int len;
    	node(const LL v=0,const int l=0){val=v;len=1;}
    }ta[maxn<<2],tb[maxn<<2];
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    node merge(node l,node r){
    	node ret;
    	ret.val=(l.val*pw[r.len]%TT+r.val)%TT;
    	ret.len=l.len+r.len;
    	return ret;
    }
    
    void pushup(int k){
    	ta[k]=merge(ta[k<<1],ta[k<<1|1]);
    	tb[k]=merge(tb[k<<1|1],tb[k<<1]);
    }
    
    void update(int k,int l,int r,int x){
    	if(l==r){
    		ta[k]=tb[k]=node(1,1);
    		return ;
    	}
    	int mid=l+r>>1;
    	if(x<=mid)update(k<<1,l,mid,x);
    	else update(k<<1|1,mid+1,r,x);
    	pushup(k);
    }
    
    node query1(int k,int l,int r,int x,int y){
    	if(x<=l&&r<=y)return ta[k];
    	int mid=r+l>>1;
    	if(y<=mid)return query1(k<<1,l,mid,x,y);
    	if(mid<x)return query1(k<<1|1,mid+1,r,x,y);
    	return merge(query1(k<<1,l,mid,x,mid),query1(k<<1|1,mid+1,r,mid+1,y));
    }
    
    node query2(int k,int l,int r,int x,int y){
    	if(x<=l&&r<=y)return tb[k];
    	int mid=r+l>>1;
    	if(y<=mid)return query2(k<<1,l,mid,x,y);
    	if(mid<x)return query2(k<<1|1,mid+1,r,x,y);
    	return merge(query2(k<<1|1,mid+1,r,mid+1,y),query2(k<<1,l,mid,x,mid));
    }
    
    void build(int k,int l,int r){
    	if(l==r){
    		ta[k]=tb[k]=node(0,1);
    		return ;
    	}
    	int mid=r+l>>1;
    	build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    	pushup(k);
    }
    
    int main(){
    	freopen("P2757.in","r",stdin);
    	freopen("P2757.out","w",stdout);
    	T=read();
    	while(T--){
    		int flg=0;
    		N=read();
    		pw[0]=1;
    		for(int i=1;i<=N;i++)pw[i]=pw[i-1]*bas%TT;
    		build(1,1,N);
    		for(int i=1;i<=N;i++){
    			int x=read();
    			if(flg)continue;
    			update(1,1,N,x);
    			int k=min(x-1,N-x);
    			if(k<=0) continue;
    			if(query1(1,1,N,x-k,x-1).val!=
    			query2(1,1,N,x+1,x+k).val){
    				printf("Y
    ");
    				flg=1;
    			}
    		}
    		if(!flg)printf("N
    ");	
    	}
    	return 0;
    }
    
  • 相关阅读:
    python中不可变数据类型和可变数据类型
    你分得清Python中:“索引和切片”吗?
    Python Django中一些少用却很实用的orm查询方法
    jQuery on()方法
    jquery.flexslider-min.js实现banner轮播图效果
    jQuery 树型菜单插件(Treeview)
    jQuery Growl 插件(消息提醒)
    jQuery Autocomplete 用户快速找到并从预设值列表中选择
    jQuery Accordion 插件用于创建折叠菜单
    jquery.validate.js 验证框架详解
  • 原文地址:https://www.cnblogs.com/martian148/p/13889072.html
Copyright © 2011-2022 走看看