zoukankan      html  css  js  c++  java
  • 「NOIP2021模拟赛8.18 C」另一个序列(aseq)题解

    题目大意

    「NOIP2021模拟赛8.18 C」另一个序列(aseq)

    定义一个序列的所有连续子序列中都要至少存在一个数在这个子序列中只出现过一次,称这个序列是合理的,判断给出的序列是否合理

    问题求解

    考试的时候一直在思考如何用树状数组+扫描线来进行连续子序列是否合法的判断,但是发现无论怎么样至少要枚举所有子序列才能求解,逃不掉(O(n^2))

    所以我们要换种思考问题的方式,很容易可以求出(pre[x],nxt[x])分别表示前面第一个一样的和后面第一个一样的

    然后在((L,R))内存在一个点(i)满足(pre[x]<L&&nxt[x]),显然在((L,R))的子区间内,过(i)的区间肯定是合理的,所以要考虑不过(i)的区间,如果不存在这样的点,显然就不是合理的了

    就可以分别(check(L,x-1)&&check(x+1,R))由于要保证时间复杂度,自然而然的就想到了有点类似启发式合并一样的想法,从中间开始找就可以保证是(log)级别的了

    代码实现

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=200005;
    int T,N,a[maxn],b[maxn],tot,pre[maxn],nxt[maxn],vis[maxn];
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch>'9'||ch<'0'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    bool check(int L,int R){
    	if(L>=R)return 1;
    	int mid=(R-L>>1)+L;
    	for(int i=0;mid-i>=L&&mid+i<=R;i++){
    		if(pre[mid+i]<L&&nxt[mid+i]>R)return check(L,mid+i-1)&check(mid+i+1,R);
    		if(pre[mid-i]<L&&nxt[mid-i]>R)return check(L,mid-i-1)&check(mid-i+1,R);
    	}
    	return 0;
    }
    int main(){
    	freopen("aseq.in","r",stdin);
    	freopen("aseq.out","w",stdout);
    	T=read();
    	while(T--){
    		N=read();
    		for(int i=1;i<=N;i++)a[i]=b[i]=read();
    		tot=unique(b+1,b+1+N)-b-1;
    		sort(b+1,b+1+tot);
    		for(int i=1;i<=N;i++)a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
    		memset(vis,0,sizeof vis);
    		for(int i=1;i<=N;i++){
    			if(vis[a[i]])pre[i]=vis[a[i]];
    			else pre[i]=0;vis[a[i]]=i;
    		}
    		memset(vis,0,sizeof vis);
    		for(int i=N;i;i--){
    			if(vis[a[i]])nxt[i]=vis[a[i]];
    			else nxt[i]=N+1;vis[a[i]]=i;
    		}
    		printf("%s
    ",check(1,N)?"YES":"NO");
    	}
    	return 0;
    }
    
  • 相关阅读:
    龙年新作:水印文字添加工具源码摘要
    C语言关键字 浪里白条:goto
    继续聊WPF——自定义命令
    CSS3新的鼠标样式介绍
    C语言深入理解 常量与变量
    XCode 4 不能运行的解决办法
    Runtime专题:详解IOS开发应用之并发Dispatch Queues
    C语言关键字 乱世枭雄:static与extern
    一步步带你做vue后台管理框架(一)——介绍框架
    怎么在谷歌浏览器中安装.crx扩展名的离线Chrome插件?
  • 原文地址:https://www.cnblogs.com/martian148/p/15158448.html
Copyright © 2011-2022 走看看