【CF1053E】Euler tour
【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的更多相关文章
- 【BZOJ3060】[Poi2012]Tour de Byteotia 并查集
[BZOJ3060][Poi2012]Tour de Byteotia Description 给定一个n个点m条边的无向图,问最少删掉多少条边能使得编号小于等于k的点都不在环上. Input ...
- 【POJ】【1637】Sightseeing tour
网络流/最大流 愚人节快乐XD 这题是给一个混合图(既有有向边又有无向边),让你判断是否有欧拉回路…… 我们知道如果一个[连通]图中每个节点都满足[入度=出度]那么就一定有欧拉回路…… 那么每条边都可 ...
- 【SPOJ】【1825】Free Tour 2
点分治 点分治的例题2(本题代码结果为TLE……) 强烈谴责卡时限QAQ,T了无数次啊无数次…… 不过在N次的静态查错中倒是加深了对点分治的理解……也算因祸得福吧(自我安慰一下) TLE后的改进:每棵 ...
- jzoj3760. 【BJOI2014】Euler
题目大意: 欧拉函数 φ(n) 定义为不超过正整数 n 并且与 n 互素的整数的数目. 可以证明 φ(n) = n ∗ ∏ (1 − 1 / pi). 其中 pi(1 <= i <= ...
- [jzoj]3760.【BJOI2014】Euler
Link https://jzoj.net/senior/#main/show/3760 Description 欧拉函数 φ(n) 定义为不超过正整数 n 并且与 n 互素的整数的数目. 可以证 ...
- 【CF666B】World Tour(贪心,最短路)
题意:给你一张有向图,叫你给出四个点的序列a,b,c,d,使得这四个点依次间的最短路之和最大.(4 ≤ n ≤ 3000, 3 ≤ m ≤ 5000) 思路:O(n4)可用来对拍 我们需要O(n2)级 ...
- 【SPOJ1825】Free tour II (点分治,启发式)
题意: 边权可能为负 思路: 感觉我自己写的还是太过僵硬了,可以灵活一点,比如可以多写几个不同的dfs求出不同的信息,而不是压到同一个dfs里 #include<cstdio> #incl ...
- 【HDOJ6322】Euler Function(数论)
题意: 思路: #include <stdio.h> #include <vector> #include <algorithm> #include <str ...
- 【CF1137C】 Museums Tour 拆点+缩点
https://codeforc.es/contest/1137/problem/C # 题意 给你n个点,每个点有k天博物馆开放时间的安排表. 有m条单向道路,走过一条边需要一个晚上,经过后就是第二 ...
随机推荐
- java学习路线推荐,希望能帮到你
很多小白刚开始学习java时,肯定迷惘过,因为对java基本是啥也不懂的,一直想知道java的具体学习路线,我曾经也看了许许多多的java经验分享的帖子,评论,以及其他各种培训机构所谓的学习路线,特别 ...
- ETCD:gRPC命名与发现
原文地址:gRPC naming and discovery etcd提供一个gRPC解析器支持备用的命名系统,该命名系统从etcd获取主机以发现gRPC服务.以下机制基于监视对以服务名称为前缀的Ke ...
- 解决CentOS7 Local time比实际时间相差8小时
GPS系统中有两种时间区分,UTC就0时区的时间,CST为本地时间,如北京为早上八点(东八区),UTC时间比北京时晚八小时; CST:China Standard Time,UTC+8:00 中国沿海 ...
- Python调用Redis
#!/usr/bin/env python # -*- coding:utf-8 -*- # ************************************* # @Time : 2019/ ...
- PAT 1007 Maximum Subsequence Sum 最大连续子序列和
Given a sequence of K integers { N1, N2, …, NK }. A continuous subsequence is defined to be { Ni, Ni ...
- Inherit from the Business Class Library Class 继承自Business类(EF)
In this lesson, you will learn how to implement business classes for your application using the Busi ...
- JQuery 获取元素到浏览器可视窗口边缘的距离
获取元素到浏览器可视窗口边缘的距离 by:授客 QQ:1033553122 1. 测试环境 JQuery-3.2.1.min.js 下载地址: https://gitee.com/ishouke/ ...
- IIFE,回调函数
回调函数: 当函数A作为一个参数在函数B中被调用时,就称A为B的回调函数 IIFE:匿名函数自调用 (function(){})() 作用:防止污染全局命名空间 隐藏实现
- JavaScript---动态加载script和style样式
一个网页里面的内容理解为一个XML或者说网页本身也就是一个XML文档,XML文档都有很特殊的象征:"标签"也叫"节点". 一个基本的网页格式 <!DOCT ...
- frp内网渗透实现ssh外网访问家里树莓派(树莓派raspbian系统+腾讯云contos7)
只有信用卡大小的它,同时也是一台功能完备的电脑(树莓派),把内网能玩的功能都玩了个遍,自然就有了外网访问这台树莓派的需求.一样也是查阅了无数文章,研究了无数个方案,最终试验成功用FRP实现了内网穿透, ...