2019CCPC Final K. Russian Dolls on the Christmas Tree
题目大意
一棵 \(n(1\leq n\leq 2\times 10^5)\) 个节点以 \(1\) 为根的树,分别求以 \(1\sim n\) 为根的子树中有多少个节点编号连续的段。 \(T(1\leq T\leq 10)\) 组数据, \(\sum_{i=1}^{T}n\leq 10^6\) 。
思路
将子树按 \(dfs\) 序转化为区间,之后求区间内有多少个数字连续的段。我们可以使用树状数组,用一个 \(vis[\space]\) 来记录每个数字是否出现过,我们对区间从前往后遍历,对于每一个数字 \(i\) ,如果 \(i-1,i+1\) 都没有出现过,说明是新的一段,于是在这个位置 \(+1\) ;如果二者仅有一个出现过,说明段数没有变化;如果都出现过,说明有两个段被合并为了一个段,于是需要在这个位置 \(-1\)。这样查询区间 \([1,x]\) 的时候就是对前 \(x\) 个位置上的数求和即可。如果查询的左端点不是 \(1\) 那么我们要考虑去掉左侧不属于查询区间部分的影响,对于其中的每一个数字 \(i\) ,其会影响到 \(i-1,i+1\) 对应位置上的值,因为 \(i\) 是更早出现的,所以此时我们把那两个值 \(+1\) , 将 \(i\) 对应位置上的值置为 \(0\) ,然后对于查询区间 \([l,r]\) ,答案依然是前 \(r\) 个值的和。我们对所有询问按查询的左端点排序,依次查询即可,复杂度 \(O(nlogn)\) 。
代码
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
#define all(x) x.begin(),x.end()
//#define int LL
//#define lc p*2+1
//#define rc p*2+2
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#pragma warning(disable :4996)
const long double eps = 1e-15;
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 200010;
int T, N, cnt = 0;
vector<int>G[maxn];
int dfn[maxn], in[maxn], out[maxn], rnk = 0, A[maxn];
bool vis[maxn];
int dat[maxn], n, ans[maxn], val[maxn];
struct Query{
int l, r, id;
}Q[maxn];
bool cmp(const Query& a, const Query& b)
{
return a.l < b.l;
}
void add(int i, int x)
{
while (i <= n)
{
dat[i] += x;
i += i & (-i);
}
}
int sum(int i)
{
int ans = 0;
while (i)
{
ans += dat[i];
i -= i & (-i);
}
return ans;
}
void add_edge(int from, int to)
{
G[from].push_back(to);
G[to].push_back(from);
}
void dfs(int v, int p)
{
in[v] = dfn[v] = ++rnk;
A[dfn[v]] = v;
val[dfn[v]] = 0;
for (int i = 0; i < G[v].size(); i++)
{
int to = G[v][i];
if (to == p)
continue;
dfs(to, v);
}
out[v] = rnk;
}
void solve()
{
rnk = 0;
dfs(1, 0);
n = N;
for (int i = 1; i <= N; i++)
{
if (!vis[A[i] + 1] && !vis[A[i] - 1])
{
add(i, 1);
val[i]++;
}
else if (vis[A[i] + 1] && vis[A[i] - 1])
{
add(i, -1);
val[i]--;
}
vis[A[i]] = true;
}
for (int i = 1; i <= N; i++)
Q[i] = Query({ in[i], out[i], i });
sort(Q + 1, Q + N + 1, cmp);
int nl = 1;
for (int i = 1; i <= N; i++)
{
int l = Q[i].l, r = Q[i].r;
while (nl < l)
{
if (A[nl] != N && dfn[A[nl] + 1] > nl)
{
add(dfn[A[nl] + 1], 1);
val[dfn[A[nl] + 1]]++;
}
if (A[nl] != 1 && dfn[A[nl] - 1] > nl)
{
add(dfn[A[nl] - 1], 1);
val[dfn[A[nl] - 1]]++;
}
add(nl, -val[nl]);
val[nl] = 0;
nl++;
}
ans[Q[i].id] = sum(r);
}
cout << "Case #" << cnt << ": ";
for (int i = 1; i <= N; i++)
cout << ans[i] << (i == N ? endl : ' ');
}
int main()
{
IOS;
cin >> T;
while (T--)
{
memset(vis, false, sizeof(vis));
memset(dat, 0, sizeof(dat));
cnt++;
cin >> N;
int u, v;
for (int i = 1; i <= N; i++)
G[i].clear();
for (int i = 1; i < N; i++)
{
cin >> u >> v;
add_edge(u, v);
}
solve();
}
return 0;
}
2019CCPC Final K. Russian Dolls on the Christmas Tree的更多相关文章
- POJ Big Christmas Tree(最短的基础)
Big Christmas Tree 题目分析: 叫你构造一颗圣诞树,使得 (sum of weights of all descendant nodes) × (unit price of the ...
- POJ3013 Big Christmas Tree[转换 最短路]
Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 23387 Accepted: 5 ...
- poj 3013 Big Christmas Tree (最短路径Dijsktra) -- 第一次用优先队列写Dijsktra
http://poj.org/problem?id=3013 Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total S ...
- poj 3013 Big Christmas Tree Djistra
Big Christmas Tree 题意:图中每个节点和边都有权值,图中找出一颗树,树根为1使得 Σ(树中的节点到树根的距离)*(以该节点为子树的所有节点的权值之和) 结果最小: 分析:直接求出每个 ...
- POJ 3013 Big Christmas Tree(最短Dijkstra+优先级队列优化,SPFA)
POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意: 圣诞树是由n个节点和e个边构成的,点编号1-n. ...
- poj 3013 Big Christmas Tree
Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 20974 Accepted: 4 ...
- Big Christmas Tree(poj-3013)最短路
Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 25823 Accepted: 5 ...
- 2019CCPC秦皇岛 K MUV LUV UNLIMITED(博弈)
MUV LUV UNLIMITED Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU - 5156 Harry and Christmas tree
题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=5156 题意 : 给一颗编号为1-n的以1为根的树, 已知有m个颜色的礼物分布在某些节点上(同一节点 ...
随机推荐
- Linux下安装confluence汉化破解版
Atlassian Confluence(简称Confluence)是一个专业的wiki程序.它是一个知识管理的工具,通过它可以实现团队成员之间的协作和知识共享.Confluence 不是一个开源软件 ...
- golang源码阅读:VictoriaMetrics中的协程优先级的处理方式
在阅读VictoriaMetrics的源码的时候,读到了那么平平无奇的一段: // AddRows adds the given mrs to s. func (s *Storage) AddRows ...
- Linux定时执行.sh脚本
因为测试ffmpeg推流用flv方式的话没有做自动断流,所以要先用.sh脚本来执行关流,降低CPU和其他资源占用 首先编写.sh文件 #! /bin/bash echo "kill ffmp ...
- Kubernetes的Resource和Dashboard(十三)
一.Resource和Dashboard 1.1.Resource 因为K8S的最小操作单元是Pod,所以这里主要讨论的是Pod的资源 官网:https://kubernetes.io/docs/co ...
- 一条SQL更新语句是如何执行的
文章首发于公众号「蝉沐风」,认真写好每一篇文章,欢迎大家关注交流 这是图解MySQL的第2篇文章,这篇文章会通过一条SQL更新语句的执行流程让大家清楚地明白: 什么是InnoDB页?缓存页又是什么?为 ...
- (4)什么是Ribbon负载均衡
4.Ribbon负载均衡 上一节中,我们添加了@LoadBalanced注解,即可实现负载均衡功能,这是什么原理呢? 4.1.负载均衡原理 SpringCloud底层其实是利用了一个名为Ribbon的 ...
- Spring学习一: Ioc容器
Spring 容器: Spring 容器是Spring框架的核心.Spring容器将创建Bean对象实例,把它们联系在一起,配置它们,并管理它们整个生命周期从创建到销毁.Spring 容器通 ...
- JAVA类加载器一 父类委托机制
感谢原文作者:不将就! 原文链接:https://www.cnblogs.com/byron0918/p/5770653.html 类加载器负责将.class文件加载到内存中,并为之生成对应的Clas ...
- iOS 学习资料Blog 技术论坛等,不断添加中。。。。
iOS 学习资料整理 http://www.jianshu.com/p/dc81698a873c 中文 iOS/Mac 开发博客列表 https://github.com/tangqiaobo ...
- Java--面向对象设计
[转载自本科老师上课课件] 问题一: 在一个软件的功能模块中,需要一种图像处理的功能.该图像处理的策略(如何处理)与图像的内容是相关的.如:卫星的运行图片,使用策略A处理方式,如果是卫星内云图片,则需 ...