题解:POI2012 Salaries

Description

The Byteotian Software Corporation (BSC) has \(n\) employees.

In BSC's strict hierarchy, each employee has a direct supervisor, except the CEO, to whom all other BSC employees answer, directly or not.

Each employee has a unique monthly salary, and all their salaries range from 1 to \(n\) bythalers.

Each supervisor earns more than each of their subordinates.

According to Byteotian law, the salaries of employees on certain posts may be publicly disclosed.

Furthermore, if the salary of an employee is disclosed, then the salary of their supervisor is also disclosed.

The Byteotian Internal Revenue Anti-Corruption Service (BIRAS) has decided to investigate BSC.

Before BIRAS enters BSC with a warrant, they intend to learn the salaries of all BSC employees that are not disclosed but can be determined from those that are disclosed.

题意:

给一棵 \(n\) 个结点的树,点权取 \(1 \sim n\) 且 各不相同。

满足任意非根结点的权值一定比它的父节点权值小。

现在自顶向下地已知一些点的权值(即若某非根点权值已知,其父节点的权值也一定已知),

问哪些点的权值能唯一确定。

\(n \leq 1e6\)

Algorithm

这是一道 十分有趣 而 一言难尽 的题目。

我们先从两个例子入手,试图理解一下「唯一确定」的意思。

例一

在这里,由于点 \(b\) 是点 \(3\) 的孙子结点,最大只能取 \(1\) ,因此唯一确定 \(b = 1\)

同时,点 \(a\) 是点 \(3\) 的儿子结点,可能的取值有 \(1, 2\) ,但因为 \(b = 1\) ,所以唯一确定 \(a = 2\)

例二

此处 \(a, b\) 都是 \(3\) 的子节点,他们的取值可能为 \(1, 2\) ,但并不能唯一确定一种对应关系。

\(c\) 是 \(5\) 的子节点,可能的取值有 \(1, 2, 4\) 。但因为 \(a, b\) 对应 \(1, 2\) ,只能有 \(c = 4\) ,这也是唯一确定的。

揆诸上例与题面自顶向下给权的性质,我们容易发现:

  1. 对于任意一个未确定的结点,它的可能取值范围总是 \((0,x_i]\) ,

    其中, \(x_i\) 是由树的结构与已知点权共同决定的。

  2. 一个点的权能被唯一确定,当且仅当其取值范围为 \((x_i - 1, x_i]\)

  3. 当我们确定了 \(k\) 个结点的取值后,剩余的未确定结点的取值范围就会变化为 \((k, x_i]\)

  4. 确定点权的顺序总是从小到大的。

(写成左开右闭的形式仅仅是为了规避区间左右端点相等的写法,没别的意思)

接下来只要模拟上述的推理即可。

我们可以首先一次 DFS 遍历整棵树,根据树结构维护每个点可能的最大取值。

特别注意此处有个坑,如果仅根据点的祖先结点取值和深度计算 \(x_i\) 的话代码就是错误的。

经过这种方法计算出的值 \(x'_i\) 可能已经被某个已知点取了,你需要尝试不断减少 \(x'_i\) 的值直到其符合定义为止。

这个"不断减少"的过程可以预处理出来。

DFS 之后,我们可以根据最大取值将点排序,再依次考虑每个权是否可以被确定或唯一确定。

这个算法描述起来还挺模糊的……不如直接读代码:

#include<bits/stdc++.h>
using namespace std; template<class T>
inline void read(T &x)
{
char c = getchar(); x = 0;
while(c < '0' || '9' < c) c = getchar();
while('0' <= c && c <= '9')
{
x = (x << 1) + (x << 3) + c - 48;
c = getchar();
}
} const int INF = 0x7f7f7f7f;
typedef pair<int, int> Node;
vector<Node> ord; template<const int N, const int M>
class Tree {
private:
int beg[N], nex[M], tar[M], len;
public:
int vap[N], van[N];
bool vis[N]; Tree():len(1) {}
inline void add_egde(int a, int b)
{
++len, tar[len] = b;
nex[len] = beg[a], beg[a] = len;
} void dfs(int cur, int val)
{
if(!vap[cur]) ord.push_back(Node(val, cur));
for(int i = beg[cur]; i; i = nex[i])
{
if(vap[tar[i]]) dfs(tar[i], vap[tar[i]]);
else dfs(tar[i], van[val - 1]);
}
}
}; Tree<1048576, 1048576> T;
int main()
{
int n, rot; read(n);
for(int i = 1, x; i <= n; ++i)
{
read(x), read(T.vap[i]); if(x == i) rot = i, T.vap[i] = n;
else T.add_egde(x, i); if(T.vap[i])
T.vis[T.vap[i]] = true;
} for(int i = 1; i <= n; ++i)
{
if(T.vis[i]) T.van[i] = T.van[i - 1];
else T.van[i] = i;
} T.dfs(rot, n);
sort(ord.begin(), ord.end()); int done = 0, len = ord.size();
for(int i = 1, j = 0; i <= n; i++)
{
if(T.vis[i]) done++;
else
{
int cnt = 0;
while(j < len && ord[j].first == i) j++, cnt++;
if(cnt == 1 && done == i - 1)
T.vap[ord[j - 1].second] = i;
done += cnt;
}
} for(int i = 1; i <= n; ++i)
printf("%d\n", T.vap[i]); return 0;
}

题解:POI2012 Salaries的更多相关文章

  1. 【BZOJ2799】[Poi2012]Salaries 乱搞

    [BZOJ2799][Poi2012]Salaries Description 给出一棵n个结点的有根树,结点用正整数1~n编号.每个结点有一个1~n的正整数权值,不同结点的权值不相同,并且一个结点的 ...

  2. [BZOJ2799][Poi2012]Salaries

    2799: [Poi2012]Salaries Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 91  Solved: 54[Submit][Statu ...

  3. [POI2012]Salaries

    题目大意: 给定一棵n带权树,每个点的权值在[1,n]范围内且互不相等,并满足子结点的权值一定小于父结点. 现在已知一个包含根结点的联通块中个点的权值,求剩下哪些点的权值能够被求出,并求出这些权值. ...

  4. bzoj 2799 [Poi2012]Salaries 性质+二分

    题目大意 给出一棵n个结点的有根树,结点用正整数1~n编号. 每个结点有一个1~n的正整数权值,不同结点的权值不相同, 并且一个结点的权值一定比它父结点的权值小(根结点的权值最大,一定是n). 现在有 ...

  5. POI2012题解

    POI2012题解 这次的完整的\(17\)道题哟. [BZOJ2788][Poi2012]Festival 很显然可以差分约束建图.这里问的是变量最多有多少种不同的取值. 我们知道,在同一个强连通分 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. [Poi2012]Festival 题解

    [Poi2012]Festival 时间限制: 1 Sec  内存限制: 64 MB 题目描述 有n个正整数X1,X2,...,Xn,再给出m1+m2个限制条件,限制分为两类: 1. 给出a,b (1 ...

  8. 【题解】 [POI2012]FES-Festival (差分约束)

    懒得复制题面,戳我戳我 Question: (因为网上找不到好的翻译,这里简单复述一下) 告诉你\(m1+m2\)个约束条件,然后要你找出\(X_1-X_n\)这些数字,求满足要求的数列中不同的数字个 ...

  9. BZOJ2802: [Poi2012]Warehouse Store

    2802: [Poi2012]Warehouse Store Time Limit: 10 Sec  Memory Limit: 64 MBSec  Special JudgeSubmit: 121  ...

随机推荐

  1. 斗篷指令、属性指令、表单指令、条件指令、循环指令、js的Array操作、前台数据库、

    ```python"""1)指令 属性指令:v-bind 表达指令:v-model 条件指令:v-show v-if 循环指令:v-for 斗篷指令:v-cloak 2) ...

  2. Q200510-02-02: 重复的DNA序列 SQL解法

    重复的DNA序列所有 DNA 都由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”.在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助. 编写一个函数来 ...

  3. logback1.11的一个bug:有线程持续不断写入log文件,log文件就不会按设定以日期切换。

    此Bug的解决方案请见:https://www.cnblogs.com/xiandedanteng/p/12205422.html logback是log4j的后继者,作者也是同一人,但其中的bug不 ...

  4. 关于Vue的那些事儿

    Vue 渐进式框架 众前端周知,Vue是一套用于构建用户界面的渐进式框架,自底向上逐层应用,关注视图层.那我们就来说道说道: 渐进式:声明式渲染->组件系统->客户端路由(router)- ...

  5. Ubuntu18.04

    起因 晚上过来加班···· 问题 物理机安装ubuntu时候遇到报错信息 boot failed: please change disks and press a key to continue ht ...

  6. spring boot 在框架中注入properties文件里的值(Spring三)

    前一篇博客实现了打开第一个页面 链接:https://blog.csdn.net/qq_38175040/article/details/105709758 本篇博客实现在框架中注入propertie ...

  7. django之安装和项目创建

    dos界面下安装django 自动下载和安装:cmd:pip3 install  django 手动安装: 1.登录django官网下载django 2.下载地址:https://www.django ...

  8. python中的一些内置函数

    1.布尔类型 2.求和sum 3.取全局变量和局部变量 4.ascii码和字符集 chr().ord() 5.看某个功能下有哪些方法 help(x).dir(x) 6.exec执行python代码 7 ...

  9. [算法]美团春招笔试题C-求有趣子序列数(DP)

    题目 输入n,以及长度为n的数组元素 输出数组的非空子序列中有多少个"有趣序列"mod 998244353,有趣序列指所有元素满足arr[i]%i == 0, i从0记. 例: 输 ...

  10. day52:django:ORM单表/多表操作

    目录 1.ORM 2.ORM单表增删改查 13个必知必会的查询接口 filter基于双下划线的模糊查询 3.ORM多表增删改查 ORM 什么是ORM? ORM(object relational ma ...