前言

赛时没做出来,赛后把题补了。果然是 maroonrk 出的,名不虚传啊……真的很好的一道题目。

解法

题目中的圆周有以下几个性质:

  • 圆周上如果有相邻的等值,我们可以去掉一个而不改变答案(这个很好证明);
  • 如果 \(1\) 和 \(2\) 相邻,那么擦去 \(1\) 不影响答案;同样的道理,如果 \(3\) 和 \(4\) 相邻,擦去 \(4\) 不影响答案。

我们定义“规范化”为尽可能地多执行以上操作的过程。

任何满足要求的树也都具有满足以下条件的边:

  • 边连接的两个点在圆周上相邻;
  • 其中一个点是树的叶子。

所以,我们可以通过执行以下操作来形成满足条件的树:

  • 选择两个相邻且可连接的点并连接它们;
  • 选择其中一个点作为叶子,将它从圆周上擦除。

那么,该如何利用上述操作来简化题目呢?

我们可以发现,在“规范化”后的圆周上,我们只有可能连接编号为 \(2\) 和 \(3\) 的点。假设我们将 \(2\) 当作那片被擦掉的叶子:

  • 如果圆周上有这样的一段“弧”:\(\cdots,4,2,3,\cdots\),擦除了 \(2\) 之后 \(3\) 和 \(4\) 相邻,就可以进行“规范化”擦除,间接地相当于擦除了一对 \(2\) 和 \(4\);
  • 如果圆周上有这样的: \(\cdots,3,2,3,\cdots\),那么按照上面的思路 \(2\) 和 \(3\) 也将被擦除;
  • ……

考虑以下一系列操作:在“规范化”状态下执行上述操作,然后再次“规范化”……

如果我们也考虑把 \(3\) 当作叶子(擦除 \(3\)),这一系列操作每次可以擦除一对 \((2,3),(1,3)\) 或 \((2,4)\)。

如果可以重复上面的操作,且最终只有 \(2\) 和 \(3\) 在圆周上,我们就可以构造出满足条件的树。

所以,我们可以推出以下必要条件:

  • 设圆环上 \(i\) 的数量为 \(C_i\),则 \(C_2>C_4\) 且 \(C_3>C_1\)。

我们可以看到,实际上它也是充分条件。因为如果有顶点 \(1\) 或 \(4\) 在圆上,那么我们可以擦除一对 \((1,3)\) 或 \((2,4)\)。

我们可以在 \(O(n)\) 的时间复杂度内解决这个问题。

实现

注意到,我的代码中有一个 \(f\) 数组,其中 \(f=\{2,2,3,3\}\)。但是因为我在实现中为方便处理,将所有输入的数减去了 \(1\),所以代码中 \(f=\{1,1,2,2\}\)。

它的作用是什么呢?判断相邻的两个点能否进行规范化操作!我们注意到,如果两个点编号为 \(i,j\),\(f_i=f_j\) 的必要条件为 \(i=j\) 或 \(|i-j|=1\)。

所以,如果 \(f_i=f_j\),假设 \(f_i=i\),就代表 \(i=2\) 或 \(i=3\),不管 \(j\) 是什么,擦掉 \(j\) 都是“规范化”过程中的合法操作。

最后再用 std::map 来统计每个数出现的数量,比较后输出即可。

放代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
int t,f[4]={1,1,2,2}; cin>>t;
while(t--){
int n; cin>>n;
vector<int> a;
for(int i=0;i<n;i++){
int x; cin>>x;
if(x--;i&&f[x]==f[a.back()]){
if(f[x]==x)a.back()=x;
}
else a.emplace_back(x);
}
if(f[a[0]]==f[a.back()]){
if(f[a[0]]==a.back())a[0]=a.back();
a.pop_back();
}
vector<int> m(4); for(int i:a)m[i]++;
cout<<(m[2]>m[0]&&m[1]>m[3]?"Yes\n":"No\n");
}
return 0;
}

[AGC058C] Planar Tree 题解的更多相关文章

  1. Codeforces Round #530 (Div. 2):D. Sum in the tree (题解)

    D. Sum in the tree 题目链接:https://codeforces.com/contest/1099/problem/D 题意: 给出一棵树,以及每个点的si,这里的si代表从i号结 ...

  2. POJ 1308 Is It A Tree?--题解报告

    Is It A Tree? Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 31092   Accepted: 10549 D ...

  3. C++版 - 剑指offer 面试题39:判断平衡二叉树(LeetCode 110. Balanced Binary Tree) 题解

    剑指offer 面试题39:判断平衡二叉树 提交网址:  http://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId= ...

  4. 【文文殿下】CF1098C Construct a tree 题解

    题解 挺水的一道题. Rating $ \color{orange} {2300}$ 以下送命题. 首先我们知道,所有子树大小之和就是节点个数加上从根到所有节点的路径长度之和. 他要求度数尽可能小,所 ...

  5. BZOJ2588:Count on a tree——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2588 Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你 ...

  6. CC TSUBSTR:Substrings on a Tree——题解

    https://www.codechef.com/problems/TSUBSTR https://vjudge.net/problem/CodeChef-TSUBSTR 给一棵点权为字母的树,你只能 ...

  7. 【日常学习】【二叉树遍历】Uva548 - Tree题解

    这道题目本身不难,给出后序遍历和中序遍历,求到节点最小路径的叶子,同样长度就输出权值小的叶子. Uva上不去了,没法測.基本上是依照ruka的代码来的.直接上代码 //Uva548 Tree #inc ...

  8. SPOJ - QTREE Query on a tree题解

    题目大意: 一棵树,有边权,有两个操作:1.修改一条边的权值:2.询问两点间路径上的边的权值的最大值. 思路: 十分裸的树链剖分+线段树,无非是边权要放到深度大的一端的点上,但是有两个坑爹的地方,改了 ...

  9. 洛谷 P2633 Count on a tree 题解

    题面 对于每个点建立一颗主席树: 然后按照树上差分的思想统计主席树的前缀和: lca+主席树+前向星存表就可以了: #include <bits/stdc++.h> #define inc ...

  10. [Luogu P4178]Tree 题解(点分治+平衡树)

    题目大意 给定一棵树,边带权,问有多少点对满足二者间距离$\leq K$,$n \leq 40000$. 题解 点分治专题首杀!$Jackpot!$ (本来看着题意比较简单想捡个软柿子捏,结果手断了… ...

随机推荐

  1. 牛客刷Java记录第四天

    第一题,单选题 class Car extends Vehicle { public static void main (String[] args) { new Car(). run(); } pr ...

  2. Windows Server 2019/2016 配置自动更新和更换大陆更新服务器

    文章原地址: 运行 > gpedit.msc -> 计算机配置 -> 管理模板 -> Windows 组件 -> Windows 更新 下面中右侧三个选项是本篇教程中会介 ...

  3. Config:Spring Cloud分布式配置组件

    Config:Spring Cloud分布式配置组件 问题总结 Config? Config工作原理? Config 的特点? Config+Bus 实现配置的动态刷新? 问题答案 Config Co ...

  4. 2.elasticsearch中的mapping

    mapping 顾名思义,代表了映射关系.是文档中字段和数据类型的映射关系 为什么要了解mapping 虽然elasticsearch中已尽有的动态mapping(Dynamic Mapping),而 ...

  5. 数据结构入门之单链表代码实现(java)

    1:单链表是: 单链表是一种链式存取的 数据结构 用一组地址任意的 存储单元 存放线性表中的数据元素. 链表中的数据是以结点来表示的,每个结点的构成:元素 ( 数据元素 的映象) + 指针 (指示后继 ...

  6. 序列化性能测试:jdk和fastjson

    序列化性能测试:jdk和fastjson 我开发一个认证授权框架时,需要添加数据库存储token或者会话,于是想测试使用jdk的blob存储解析快还是存储string的json序列化解析快,从而选择他 ...

  7. MySQL进阶篇:详解索引使用_最左前缀法则

    MySQL进阶篇:第四章_四.一_ 索引使用_最左前缀法则 最左前缀法则 如果索引了多列(联合索引),要遵守最左前缀法则.最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列.如果跳跃某一列 ...

  8. 如何去学好JS的8条小建议

    摘要:如何才能学好JS?在这里给大家总结一些学习Js的经验,希望能对你们有所帮助. 在我们第一阶段完成HTML+CSS的学习之后,很多同学都会被第二阶段JS难倒--JS语法.JS数据类型.JS对象,J ...

  9. 华为云GaussDB(for openGauss)商用啦!

    摘要:截止目前,华为消费者云已在GaussDB(for openGauss)上线了40+业务,包括弹幕&评论.云空间.地理大数据等业务系统,实时为5亿+用户提供高效服务. 生命在于运动,健康打 ...

  10. 解读 SSDB、LevelDB 和 RocksDB 到 GaussDB(for Redis) 的迁移

    摘要:本期将详细介绍 SSDB.LevelDB 和 RocksDB 到 GaussDB(for Redis)的迁移. 本文分享自华为云社区<华为云PB级数据库GaussDB(for Redis) ...