【CF1053E】Euler tour

题面

CF

洛谷

大概意思是你有一棵树,然而你并不知道这棵树是啥。给你一个确定了一些位置的欧拉序(就是\(ST\)表求\(LCA\)的那个序列),问你是否存在一个合法的序列,如果可以构造出一个。

题解

首先我们一定能够确定的是以下性质:

  • \(a_1=a_{2n-1}\),因为首位肯定都是根节点
  • 如果\(a_i=a_j\),那么两个位置中间的数的个数一定是偶数个,即\(i,j\)同奇偶。因为子树内每条边都会给序列贡献两个点,所以贡献的点数一定是偶数。
  • 两个两侧端点是同一节点的区间如果有交,那么它们一定是包含关系。如果有交证明一个一定在另外一个子树内,所以必定是包含关系。

接下来考虑怎么构造,假设我们当前要构造的是区间\([l,r]\),首先这个区间要满足上面的性质。

然后从左往右扫一遍\([l,r]\),如果发现\(a_i=a_l\),证明\([lst,i]\)这段区间内是一棵子树,其中\(lst\)是\(a_i\)上一次出现的位置,那么可以递归处理这棵子树,处理完了之后可以直接删掉。

对于剩下的所有位置一定两两不成子树(如果成子树就会在前面被递归了),先统计一下总数和不同的节点数,看看空位置的数量够不够两两匹配,如果不够肯定不解。

首先空位置的数量一定要是确定的数字的两倍,那么首先从前往后填未出现过的数字把一部分空位置给填上。

然后如果连续三个位置形如\(0xy\),那么第一可以把它填成\(yxy\),如果连续三个位置形如\(xy0\),那么可以变成\(xyx\)。注意这里因为所有数字都只会出现一次,所以这样子才是对的。

这样子处理完只有一个三元组\(xyx\)只需要保留一个\(x\),于是这样子能够把所有\(0\)基本填满。

如果还有没有填满的位置,那么直接填上这段区间的根节点就行了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 1000100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
void Fail(){puts("no");exit(0);}
int n,m,a[MAX],pre[MAX],suf[MAX],vis[MAX],nxt[MAX];
void Del(int l,int r){suf[pre[l]]=suf[r];pre[suf[r]]=pre[l];}
int nw=1;
int get()
{
while(vis[nw])++nw;
if(nw>n)Fail();
vis[nw]=-1;return nw;
}
void Solve(int l,int r)
{
if((r-l)&1)Fail();
for(int i=l;i<=r;i=suf[i])
while(nxt[i])
{
if(nxt[i]>r)Fail();
Solve(suf[i],pre[nxt[i]]);
Del(suf[i],nxt[i]);
nxt[i]=nxt[nxt[i]];
}
int sum=0,cnt=0,rt=a[pre[l]];
for(int i=l;i<=r;i=suf[i])++sum,cnt+=a[i]>0;
sum=(sum+1)/2;if(cnt>sum)Fail();
for(int i=suf[l];i<=r;i=suf[i])if(!a[i]&&cnt<sum)a[i]=get(),++cnt;
if(sum==1&&cnt==0)a[l]=get();
for(int i=l;suf[i]<=r;i=suf[i])
{
while(i>l&&suf[i]<=r&&!a[pre[i]]&&a[i]&&a[suf[i]])
a[pre[i]]=a[suf[i]],Del(i,suf[i]),i=pre[pre[i]];
while(i>=l&&suf[suf[i]]<=r&&a[i]&&a[suf[i]]&&!a[suf[suf[i]]])
a[suf[suf[i]]]=a[i],Del(suf[i],suf[suf[i]]),i=pre[i];
}
for(int i=l;i<=r;i=suf[i])if(!a[i])a[i]=rt;
}
int main()
{
n=read();m=n+n-1;
for(int i=1;i<=m;++i)a[i]=read();
if(a[1]&&a[m]&&a[1]!=a[m])Fail();
a[1]=a[m]=a[1]|a[m];
for(int i=0;i<=m;++i)pre[i]=i-1,suf[i]=i+1;
for(int i=m;i;--i)if(a[i])nxt[i]=vis[a[i]],vis[a[i]]=i;
Solve(1,m);
puts("yes");for(int i=1;i<=m;++i)printf("%d ",a[i]);
puts("");return 0;
}

【CF1053E】Euler tour的更多相关文章

  1. 【BZOJ3060】[Poi2012]Tour de Byteotia 并查集

    [BZOJ3060][Poi2012]Tour de Byteotia Description 给定一个n个点m条边的无向图,问最少删掉多少条边能使得编号小于等于k的点都不在环上. Input     ...

  2. 【POJ】【1637】Sightseeing tour

    网络流/最大流 愚人节快乐XD 这题是给一个混合图(既有有向边又有无向边),让你判断是否有欧拉回路…… 我们知道如果一个[连通]图中每个节点都满足[入度=出度]那么就一定有欧拉回路…… 那么每条边都可 ...

  3. 【SPOJ】【1825】Free Tour 2

    点分治 点分治的例题2(本题代码结果为TLE……) 强烈谴责卡时限QAQ,T了无数次啊无数次…… 不过在N次的静态查错中倒是加深了对点分治的理解……也算因祸得福吧(自我安慰一下) TLE后的改进:每棵 ...

  4. jzoj3760. 【BJOI2014】Euler

    题目大意: 欧拉函数  φ(n)  定义为不超过正整数 n 并且与 n 互素的整数的数目. 可以证明 φ(n) =  n ∗ ∏ (1 − 1 / pi). 其中 pi(1 <= i <= ...

  5. [jzoj]3760.【BJOI2014】Euler

    Link https://jzoj.net/senior/#main/show/3760 Description 欧拉函数  φ(n)  定义为不超过正整数 n 并且与 n 互素的整数的数目. 可以证 ...

  6. 【CF666B】World Tour(贪心,最短路)

    题意:给你一张有向图,叫你给出四个点的序列a,b,c,d,使得这四个点依次间的最短路之和最大.(4 ≤ n ≤ 3000, 3 ≤ m ≤ 5000) 思路:O(n4)可用来对拍 我们需要O(n2)级 ...

  7. 【SPOJ1825】Free tour II (点分治,启发式)

    题意: 边权可能为负 思路: 感觉我自己写的还是太过僵硬了,可以灵活一点,比如可以多写几个不同的dfs求出不同的信息,而不是压到同一个dfs里 #include<cstdio> #incl ...

  8. 【HDOJ6322】Euler Function(数论)

    题意: 思路: #include <stdio.h> #include <vector> #include <algorithm> #include <str ...

  9. 【CF1137C】 Museums Tour 拆点+缩点

    https://codeforc.es/contest/1137/problem/C # 题意 给你n个点,每个点有k天博物馆开放时间的安排表. 有m条单向道路,走过一条边需要一个晚上,经过后就是第二 ...

随机推荐

  1. Iris入门操练1

    选一个框架,慢慢熟悉··· 按官网文档,先走一次.. package main import ( "github.com/kataras/iris/v12" "githu ...

  2. numpy-np.ceil,np.floor,np.expand_dims方法

    np.ceil(多维数组):对多维数组的各个数向上取整 np.floor(多维数组):对多维数组的各个数向下取整 np.expand_dims(x,axis = 0):在x的第一维度上插入一个维度,a ...

  3. R3环申请内存时页面保护与_MMVAD_FLAGS.Protection位的对应关系

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 技术学习来源:火哥(QQ:471194425) R3环申请内存时页 ...

  4. Mybatis的原理分析1(@Mapper是如何生效的)

    接着我们上次说的SpringBoot自动加载原理.我们大概明白了在maven中引入mybatis后,这个模块是如下加载的. 可能会有人问了,一般我们的dao层都是通过Mapper接口+Mapper.x ...

  5. 我来告诉你:VS2019开发ASP.NET Core 3.0 Web项目,修改视图后,刷新浏览器看不到修改后的效果怎么处理

    VisualStudio2019下一个2.2另一个3.0页面修改如下,但是3.0刷新没有任何变化,难道VS以后不能做前端开发了?大家可能没有看官方文档 根据文章所说你需要: 1.安装 Microsof ...

  6. centos7.2安装及管理docker

    使用的操作系统是是centos7.2,按照官方的推荐的配置,把linux内核升级到3.8以上.安装步骤如下: 1.升级内核版本(包含aufs)cd /etc/yum.repos.dwget http: ...

  7. ArcGIS api for JavaScript 3.27 按需显示需要的图层

    实例:现有一图层服务,现需要动态显示该图层中的一部分内容:点击一个图例,只显示这个图例的内容,再点击别的图例,原来的内容不消失,再次点击已被点击的图例才会消失. 思路:setLayerDefiniti ...

  8. ABP入门教程11 - 展示层实现增删改查-视图

    点这里进入ABP入门教程目录 创建目录 在展示层(即JD.CRS.Web.Mvc)的Views下新建文件夹Course //用以存放Course相关视图 创建视图 在JD.CRS.Web.Mvc/Vi ...

  9. 034.认证方式 | 基本认证 、Token认证、 AK/SK认证

    认证方式 关于认证: https://www.cnblogs.com/badboyh2o/p/11068779.html https://www.cnblogs.com/badboyh2o/p/110 ...

  10. Data Management Technology(1) -- Introduction

    1.Database concepts (1)Data & Information Information Is any kind of event that affects the stat ...