首先,我们将题目理解成若\(i\)与\(j\)距离恰好为\(3\),则不可能\(p_i \equiv p_j \equiv 1 \space or \space 2 (\bmod 3)\)。这就相当于我们要构造一个大小为\([\frac{n + 1}{3}]\)的点集\(A_2\),用来放所有模3余2的数,再构造一个大小为\([\frac{n + 2}{3}]\)的点集\(A_1\),用来放所有模3余1的数。需要满足这两个集合交集为空,且若\(i\)与\(j\)距离为\(3\),则它们不在同一个集合内。

发现距离为\(3\)的点连成的图性质是不好的,唯一好的性质就是:它是二分图。我们不妨大胆地把条件加强为:构造这样的点集\(A_1, A_2\),使得它们全部再二分图的同一边。

我们把树按深度奇偶染色,不妨设染一种颜色的点数为\(X\),另一种为\(Y\),且\(X \leq Y\)。

若\(X \ge [\frac{n + 1}{3}]\)且\(Y \ge [\frac{n + 2}{3}]\),我们就在\(X\)中任意取\([\frac{n + 1}{3}]\)个点作为\(A_2\),在\(Y\)中任意取\([\frac{n + 2}{3}]\)个点作为\(A_1\)即可。

否则我们容易证明\(Y \ge [\frac{n + 1}{3}] + [\frac{n + 2}{3}]\),在\(Y\)中任意找两个集合的点即可。

代码如下:

#include <bits/stdc++.h>
using namespace std; const int N = 200005; template <class T>
void read (T &x) {
int sgn = 1;
char ch;
x = 0;
for (ch = getchar(); (ch < '0' || ch > '9') && ch != '-'; ch = getchar()) ;
if (ch == '-') ch = getchar(), sgn = -1;
for (; '0' <= ch && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
x *= sgn;
}
template <class T>
void write (T x) {
if (x < 0) putchar('-'), write(-x);
else if (x < 10) putchar(x + '0');
else write(x / 10), putchar(x % 10 + '0');
} struct edge {
int to, nxt;
} tree[N << 1];
int n, col[N], head[N], perm[N], cnt = 0, cnt0 = 0, cnt1 = 0;
void addedge (int u, int v) {
edge e = {v, head[u]};
tree[head[u] = cnt++] = e;
} void dfs (int u, int fa) {
for (int i = head[u]; ~i; i = tree[i].nxt) {
int v = tree[i].to;
if (v != fa) {
col[v] = col[u] ^ 1;
dfs(v, u);
}
}
} int main () {
read(n);
for (int i = 1; i <= n; i++) head[i] = -1; for (int i = 1; i < n; i++) {
int u, v;
read(u), read(v);
addedge(u, v), addedge(v, u);
}
col[1] = 0, dfs(1, 0); for (int i = 1; i <= n; i++) {
if (col[i] == 0) cnt0++;
else cnt1++;
} if (cnt0 > cnt1) {
for (int i = 1; i <= n; i++) col[i] ^= 1;
swap(cnt0, cnt1);
}
int bound0 = n / 3, bound1 = (n + 1) / 3, bound2 = (n + 2) / 3;
if (cnt0 >= bound1 && cnt1 >= bound2) {
int tot0 = 0, tot1 = 0, tot2 = 0;
for (int i = 1; i <= n; i++) {
if (col[i] == 0) {
if (tot2 >= bound1) perm[i] = 3 * ++tot0;
else perm[i] = 3 * ++tot2 - 1;
}
else {
if (tot1 >= bound2) perm[i] = 3 * ++tot0;
else perm[i] = 3 * ++tot1 - 2;
}
}
}
else {
int tot0 = 0, tot1 = 0, tot2 = 0;
for (int i = 1; i <= n; i++) {
if (col[i] == 0) perm[i] = 3 * ++tot0;
else {
if (tot1 < bound2) perm[i] = 3 * ++tot1 - 2;
else if (tot2 < bound1) perm[i] = 3 * ++tot2 - 1;
else perm[i] = 3 * ++tot0;
}
}
}
for (int i = 1; i <= n; i++) write(perm[i]), putchar(' ');
putchar('\n');
return 0;
}

Social Infrastructure Information Systems Division, Hitachi Programming Contest 2020 C题题解的更多相关文章

  1. Social Infrastructure Information Systems Division, Hitachi Programming Contest 2020 D题题解

    将题意转换为一开始\(t = 0\),第\(i\)个操作是令\(t \leftarrow (a_i + 1) t + (a_i + b_i + 1)\).记\(A_i = a_i + 1, B_i = ...

  2. HHKB Programming Contest 2020 D - Squares 题解(思维)

    题目链接 题目大意 给你一个边长为n的正方形和边长为a和b的正方形,要求把边长为a和b的正方形放在长度为n的正方形内,且没有覆盖(可以相邻)求有多少种放法(mod 1e9+7) 题目思路 这个思路不是 ...

  3. (寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽题)

    layout: post title: (寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽题) author: " ...

  4. M-SOLUTIONS Programming Contest 2020 题解

    M-SOLUTIONS Programming Contest 2020 题解 目录 M-SOLUTIONS Programming Contest 2020 题解 A - Kyu in AtCode ...

  5. 2021.7.27--Benelux Algorithm Programming Contest 2020 补提

    I Jigsaw 题目内容: 链接:https://ac.nowcoder.com/acm/contest/18454/I 来源:牛客网 You have found an old jigsaw pu ...

  6. Yahoo Programming Contest 2019 补题记录(DEF)

    D - Ears 题目链接:D - Ears 大意:你在一个\(0-L\)的数轴上行走,从整数格出发,在整数格结束,可以在整数格转弯.每当你经过坐标为\(i-0.5\)的位置时(\(i\)是整数),在 ...

  7. 2017 ACM Arabella Collegiate Programming Contest div2的题,部分题目写个题解

    F. Monkeying Around   维护点在多少个线段上 http://codeforces.com/gym/101350/problem/F 题意:有m个笑话,每个笑话的区间是[L, R], ...

  8. 带权并查集:CF-2015 ACM Arabella Collegiate Programming Contest(F题)

    F. Palindrome Problem Description A string is palindrome if it can be read the same way in either di ...

  9. atcoder Keyence Programming Contest 2020 题解

    比赛地址 A 题意:给一个\(n*m\)的初始为白色的矩阵,一次操作可以将一行或一列染成 黑色,问至少染出\(k\)个黑点的最少操作次数. \(n\),\(m\)<=100,\(k\)<= ...

随机推荐

  1. UNP——第二章,常见协议概述

    1.为什么要了解协议 程序员与协议合作,完成应用. 了解协议是为了了解协议完成了什么,提供了什么服务,自己还应该做什么. 2.从协议的角度,套接字是什么 套接字是协议的接口, IP套接字,代表可使用I ...

  2. JsonPath在接口自动化中的应用

    我理解jsonpath于json而言,就像是xpath在XML中的作用.用来确定json中某部分数据的语言.我更喜欢叫jsonpath表达式,因为这样好像是数学问题. 以前和小伙伴一起写接口自动化的时 ...

  3. ceph在centos7下一个不容易发现的改变

    在centos6以及以前的osd版本,在启动osd的时候,回去根据ceph.conf的配置文件进行挂载osd,然后进行进程的启动,这个格式是这样的 [osd.0] host = hostname de ...

  4. kettle——转换案例

    把stu1的数据按id同步到stu2,stu2有相同id则更新数据 (1)在mysql中创建两张表 mysql> create database kettle; mysql> use ke ...

  5. HBuilderX SVN地址更改(SVN服务器IP地址变更)

    HBuilderX编辑器中无法修改SVN地址,需要手动在SVN工具中修改 修改步骤: 1.右键编辑器中的SVN项目,选择打开文件所在目录 2.目录中空白处右键,选择TortoiseSVN --> ...

  6. SQL Server 数据库bak备份文件还原操作和mdf文件附加操作

    前言:现在任何软件都离不开数据的支持,数据的价值是无价的,因此数据目前显得尤为重要,日常软件生产库的数据定时或实时备份必不可少,备份出的文件也需要进行验证,下边我将介绍SQL Server数据的的备份 ...

  7. JS逆向课程笔记

    扩展知识 Sources-js代码格式化

  8. 纯干货分享!2020阿里java岗笔试面试题总结(附答案)

    前言 2020金九银十马上结束,现为大家整理了这次金九银十面试阿里的面试题总结,都是我从朋友那拿到的面试真题,话不多说,满满的干货分享给大家! int a=10是原子操作吗? 是的.  注意点: i+ ...

  9. UnitTest_墨振文档

    目录 一.框架介绍 1 二.四大组件 2 三.ddt数据驱动 3 一.框架介绍 unittest框架是python 自带的一个作为单元测试的测试框架,在最初叫pyUnit,相当与Java语言中的Jun ...

  10. 如何制作C语言基本数据类型的思维导图

    在使用C语言编写程序时,数据类型是一个非常重要的内容,任何一个不被重视的数据错误都会使编译器无法翻译,导致程序报错. 使用思维导图来梳理各个数据类型是一个很有效的记忆方法,接下来就为大家展示一下我用i ...