前言

赛时没做出来,赛后把题补了。果然是 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 来统计每个数出现的数量,比较后输出即可。

放代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main(){
  4. ios::sync_with_stdio(false);
  5. int t,f[4]={1,1,2,2}; cin>>t;
  6. while(t--){
  7. int n; cin>>n;
  8. vector<int> a;
  9. for(int i=0;i<n;i++){
  10. int x; cin>>x;
  11. if(x--;i&&f[x]==f[a.back()]){
  12. if(f[x]==x)a.back()=x;
  13. }
  14. else a.emplace_back(x);
  15. }
  16. if(f[a[0]]==f[a.back()]){
  17. if(f[a[0]]==a.back())a[0]=a.back();
  18. a.pop_back();
  19. }
  20. vector<int> m(4); for(int i:a)m[i]++;
  21. cout<<(m[2]>m[0]&&m[1]>m[3]?"Yes\n":"No\n");
  22. }
  23. return 0;
  24. }

[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. HDU-3591 混合背包

    The trouble of Xiaoqian Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  2. StingBuilder与StringBuffer包含的常见方法(图示)

    StingBuilder与StringBuffer包含的常见方法

  3. LLaMA大型语言模型

    LLaMA (Large Language Model Meta AI)是Meta公司发布的大型语言模型系列,近日LLaMA种子文件被合并到了GitHub 上,同时一些项目维护者给予了批准,目前该项目 ...

  4. Python——第四章:作用域

    作用域: 变量的访问权限 全局变量 -> 全局作用域 局部变量 -> 局部作用域(比如在函数内定义的变量,只能在函数内调用) a = 10 # 全局变量 -> 全局作用域 print ...

  5. @Conditional+@Configuration有没有搞头?

    日拱一卒,功不唐捐. 在了解 @Conditional 之前先花 10 秒钟复习一下 @Configuration 这个注解. @Configuration 是干什么? 是配合 @Bean 注解来配置 ...

  6. 使用Spring AI让你的Spring Boot应用快速拥有生成式AI能力

    之前分享了关于Spring新项目Spring AI的介绍视频.视频里演示了关于使用Spring AI将Open AI的能力整合到Spring应用中的操作,但有不少读者提到是否有博客形式的学习内容.所以 ...

  7. 详解GaussDB(DWS)的query_band负载识别与应用

    摘要:query_band是一个会话级别(session)的GUC参数,本身是字符串类型,支持任意形式字符组合. 本文分享自华为云社区<GaussDB(DWS)的query_band负载识别与应 ...

  8. CartoonGAN论文复现:如何将图像动漫化

    摘要:本案例是 CartoonGAN: Generative Adversarial Networks for Photo Cartoonization的论文复现案例. 本文分享自华为云社区<c ...

  9. KAFKA EAGLE 监控MRS kafka之操作实践

    本文分享自华为云社区<KAFKA EAGLE 监控MRS kafka之操作实践>,作者: 啊喔YeYe . 1.Kafka Eagle简介 Kafka eagle 是一款分布式.高可用的k ...

  10. 带你了解VXLAN网络中报文的转发机制

    摘要:本节以集中式VXLAN网络(手工方式建立VXLAN隧道)为例,分别介绍相同子网内.不同子网间是如何进行通信的.在了解转发机制的前提下,我们先来看下VXLAN网关有哪些种类. VXLAN二层网关与 ...