• CF1142E/1143B Lynyrd Skynyrd


    CF1142E/1143B Lynyrd Skynyrd

    • 开始读错题了,以为是连续的一段,敲完后才发现是 (subsequence) ...
    • 考虑对于 (a) 中的每个 (a_i) 找到它在排列 (p) 中的下一个元素的最左位置 (j) ,从 (i)(j) 连一条边,这样就形成了一个森林.
    • 然后 (dfs) 遍历一下,用一个栈来存储当前在路径中的点,若当前节点为 (u) ,而路径长 (geq n) ,说明路径中从 (u) 开始的 (n) 个位置构成了一个 (cyclic shift) .
    • 这样就可以处理出以点 (i) 为第一个元素,能找到的 (cyclic shift) 最后一个元素的最左位置 (minr_i).对这个东西取一下后缀 (min) ,则它表示后缀 (isim n) 中能找到的 (cyclic shift) 最后一个元素的最左位置 .
    • 对于每个询问 ((l,r)) ,只需判断是否有 (r leq minr_l​) 即可.
    • 时间复杂度 (O(n+Q)).
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    #define mp make_pair
    inline int read()
    {
    	int out=0,fh=1;
    	char jp=getchar();
    	while ((jp>'9'||jp<'0')&&jp!='-')
    		jp=getchar();
    	if (jp=='-')
    		fh=-1,jp=getchar();
    	while (jp>='0'&&jp<='9')
    		out=out*10+jp-'0',jp=getchar();
    	return out*fh;
    }
    const int MAXN=2e5+10;
    int n,m,Q;
    int a[MAXN],b[MAXN],nxp[MAXN];
    int pos[MAXN];
    queue<char> buf;
    int cnt=0,head[MAXN],to[MAXN],nx[MAXN];
    inline void addedge(int u,int v)
    {
    	++cnt;
    	to[cnt]=v;
    	nx[cnt]=head[u];
    	head[u]=cnt;
    }
    int vis[MAXN];
    int minr[MAXN];
    int stk[MAXN],tp=0;
    void dfs(int u)
    {
    	vis[u]=1;
    	stk[++tp]=u;
    	if(tp>=n)
    		minr[u]=min(minr[u],stk[tp-n+1]);
    	for(int i=head[u];i;i=nx[i])
    	{
    		int v=to[i];
    		if(!vis[v])
    			dfs(v);
    	}
    	--tp;
    }
    int main()
    {
    	n=read(),m=read(),Q=read();
    	for(int i=1;i<=n;++i)
    		a[i]=read();
    	for(int i=1;i<=m;++i)
    		b[i]=read();
    	a[0]=a[n],a[n+1]=a[1];
    	for(int i=1;i<=n;++i)
    		nxp[a[i]]=a[i+1];
    	for(int i=m;i>=1;--i)
    	{
    		pos[b[i]]=i;
    		int pre=nxp[b[i]];
    		if(pos[pre])
    			addedge(pos[pre],i);
    	}
    	memset(minr,0x7f,sizeof minr);
    	for(int i=m;i>=1;--i)
    	{
    		if(!vis[i])
    			dfs(i);
    		minr[i]=min(minr[i],minr[i+1]);
    	}
    	while(Q--)
    	{
    		int l=read(),r=read();
    		if(minr[l]<=r)
    			buf.push('1');
    		else
    			buf.push('0');
    	}
    	while(!buf.empty())
    	{
    		putchar(buf.front());
    		buf.pop();
    	}
    	return 0;
    }
    
  • 相关阅读:
    Js前端路由管理器函数
    js前端登录js脚本
    docker部署certbot与nginx来获取ssl证书添加https及自动更新
    spring boot不同版本的优雅关闭(graceful shutdown)和在windows下winsw服务方式运行的配置
    php下载
    在k8s中导出jvm内存错误dump文件到OSS
    基于alpine构建jdk镜像遇到的坑
    UML建模综述
    Web安全攻防渗透测试实战指南之工具
    数字签名、数字证书是什么?
  • 原文地址:https://www.cnblogs.com/jklover/p/10660798.html
Copyright © 2020-2023  润新知