P5666-[CSP-S2019]树的重心【树状数组】

正题

题目链接:https://www.luogu.com.cn/problem/P5666


题目大意

给出nnn个点的一棵树,对于每条边割掉后两棵树重心编号和。

1≤T≤5,1≤n≤2999951\leq T\leq 5,1\leq n\leq 2999951T5,1n299995


解题思路

编号和,所以应该是要我们枚举点然后求有多少条边割掉后它能当重心。

随便以一个点为根的话,对于一个点,割掉它子树外面的一条边,设割去的连通块大小为kkk那么需要满足,以及点xxx的最大子节点子树为fxf_xfx
{2(n−k−sx)≤n−S2fx≤n−k\left\{\begin{matrix}2(n-k-s_x)\leq n-S\\2f_x\leq n-k\end{matrix}\right.{2(nksx)nS2fxnk
移一下项就有
n−2sx≤k≤n−2fxn-2s_x\leq k\leq n-2f_xn2sxkn2fx

但是子树里面就很难搞了,因为我们需要维护子树里所有子树的大小,其中一种方法是用线段树合并或者主席树像YbtOJ#662-交通运输这题一样搞。

很麻烦对啊吧,转换一下思路。其实有一个性质就是如果我们选择了原树的重心作为根节点,那么子节点无论如何割掉子树中的边也不会是重心。

所以这样就可以去掉这种麻烦的情况了。

只考虑前面那种,我们需要找到分割大小在[n−2sx,n−2fx][n-2s_x,n-2f_x][n2sx,n2fx]这个区间的边,并且还要不在子树内。

如果不考虑不在子树内的话挺好搞,对于根节点到该节点的路径都是n−sizxn-siz_xnsizx,否则是sizxsiz_xsizx丢进树状数组里查询就好了,边往下做边改树状数组就好了。

还要减去子树内的,好像还是要和上面一样用线段树合并?

我们可以用进入子树后的总共答案减去进入子树前的总共答案就是子树里面的答案了

这样好写很多,时间复杂度O(nlog⁡n)O(n\log n)O(nlogn)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define lowbit(x) (x&-x)
using namespace std;
const ll N=3e5+10;
struct node{ll to,next;
}a[N<<1];
ll T,n,ans,tot,rt,u,v;
ll siz[N],f[N],ls[N],t1[N],t2[N];
void addl(ll x,ll y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
void Change(ll *t,ll x,ll val){x++;while(x<=n+1){t[x]+=val;x+=lowbit(x);}return;
}
ll Ask(ll *t,ll x){ll ans=0;x++;if(x>=n+1)x=n+1;else if(x<0)x=0;while(x){ans+=t[x];x-=lowbit(x);}return ans;
}
void dfs(ll x,ll fa){siz[x]=1;f[x]=0;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;dfs(y,x);siz[x]+=siz[y];f[x]=max(f[x],siz[y]);}if(max(f[x],n-siz[x])<=n/2)rt=x;return;
} 
void calc(ll x,ll fa,bool flag){Change(t1,siz[fa],-1);Change(t1,n-siz[x],1);ll tmp=Ask(t1,n-2*f[x])-Ask(t1,n-2*siz[x]-1);tmp+=Ask(t2,n-2*f[x])-Ask(t2,n-2*siz[x]-1);ans+=tmp*x;ans+=rt*(siz[x]<=n-2*siz[flag?v:u]);Change(t2,siz[x],1);for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;calc(y,x,flag);}Change(t1,siz[fa],1);Change(t1,n-siz[x],-1);ans-=(Ask(t2,n-2*f[x])-Ask(t2,n-2*siz[x]-1))*x;
}
signed main()
{scanf("%lld",&T);while(T--){memset(ls,0,sizeof(ls));tot=rt=ans=u=v=0;scanf("%lld",&n);for(ll i=1;i<n;i++){ll x,y;scanf("%lld%lld",&x,&y);addl(x,y);addl(y,x);}dfs(1,0);dfs(rt,0);for(ll i=ls[rt];i;i=a[i].next){ll y=a[i].to;if(siz[y]>siz[u])v=u,u=y;else if(siz[y]>siz[v])v=y;} memset(t1,0,sizeof(t1));memset(t2,0,sizeof(t2));for(ll i=1;i<=n;i++)Change(t1,siz[i],1);for(ll i=ls[rt];i;i=a[i].next)calc(a[i].to,rt,(a[i].to==u));printf("%lld\n",ans);} return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319028.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客题霸 牛妹的蛋糕 C++题解/答案

题目描述 众所周知&#xff0c;牛妹非常喜欢吃蛋糕。 第一天牛妹吃掉蛋糕总数三分之一&#xff08;向下取整&#xff09;多一个&#xff0c;第二天又将剩下的蛋糕吃掉三分之一&#xff08;向下取整&#xff09;多一个&#xff0c;以后每天吃掉前一天剩下的三分之一&#xff08…

计算机提示找不到vcruntime140.dll,无法继续执行代码怎么办?如何修复

“找不到vcruntime140.dll&#xff0c;无法继续执行代码”。这个问题可能会让你感到困惑&#xff0c;不知道如何解决。那么&#xff0c;vcruntime140.dll是什么文件&#xff1f;它为什么会丢失&#xff1f;又该如何解决这个问题呢&#xff1f;本文将为你详细介绍vcruntime140.d…

codeforces1486 F. Pairs of Paths(倍增+树上数数)

F. Pairs of Paths syksykCCC题解 iamhpp题解 首先说明&#xff0c;下面图片来自第一篇博客&#xff0c;下面代码照抄第二篇博客 对没有啥是自己写的&#xff08;因为我太菜~~ 从上图可以看出两条链只有一个交点可能有两种情况 交点是两条链的LCA交点是一条链的LCA而不是另一…

学习Raft算法的笔记

Raft是一种为了管理日志复制的一致性算法。它提供了和Paxos算法相同的功能和性能&#xff0c;但是它的算法结构和Paxos不同&#xff0c;使得Raft算法更加容易理解并且更容易构建实际的系统。为了提升可理解性&#xff0c;Raft将一致性算法分解成几个关键的模块&#xff0c;例如…

P3335-[ZJOI2013]蚂蚁寻路【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P3335 题目大意 给出nmn\times mnm的网格&#xff0c;每个格子有权值。一个回路在格子的边上&#xff0c;要求有2k2\times k2k次左转&#xff0c;其他都是右转&#xff0c;且最后222次一定得是右转。 求包含的格子权值和最大…

牛客题霸 最少素数拆分 C++题解/答案

牛客题霸 最少素数拆分 C题解/答案 题目描述 牛牛刚刚学习了素数的定义&#xff0c;现在给定一个正整数N&#xff0c;牛牛希望知道N最少表示成多少个素数的和。 素数是指在大于1的自然数中&#xff0c;除了1和它本身以外不再有其他因数的自然数。 提示 哥德巴赫猜想&#xf…

LOJ dfs序1234

DFS 序 1 题目要求&#xff1a; ① uuu节点权值xxx ② 询问uuu子树权值和 uuu节点权值xxx &#xff1a;直接加uuu子树权值和&#xff1a;dfs序树状数组 LOJ提交代码 DFS 序 1 DFS 序 2 题目要求&#xff1a; ① uuu节点子树权值xxx ② 询问uuu子树权值和 uuu节点子树权值xxx&…

.NET Core 必备安全措施

.NET Core大大简化了.NET应用程序的开发。它的自动配置和启动依赖大大减少了开始一个应用所需的代码和配置量&#xff0c;本文目的是介绍如何创建更安全的.NET Core应用程序。1.在生产中使用HTTPS传输层安全性&#xff08;TLS&#xff09;是HTTPS的官方名称&#xff0c;你可能听…

CF1370F2-The Hidden Pair(Hard Version)【交互题,二分】

正题 题目链接:https://www.luogu.com.cn/problem/CF1370F2 题目大意 TTT组数据&#xff0c;给出nnn个点的一棵树&#xff0c;有两个隐藏的关键点。你每次可以询问一个点集&#xff0c;交互库会回答这个点集中的一个点满足它到两个关键点的距离和最小&#xff0c;和这个距离。…

牛客题霸题目及题解汇总

牛客题霸 单链表的选择排序 C题解/答案牛客题霸 最少素数拆分 C题解/答案牛客题霸 两数之和 C题解/答案牛客题霸 反转链表 C题解/答案牛客题霸 二分查找 C题解/答案牛客题霸 判断链表中是否有环 C题解/答案牛客题霸 转圈打印矩阵 C题解/答案牛客题霸 [斐波那契数列] C题解/答牛…

HDU5126 stars(4维偏序->cdq套cdq+树状数组)

stars 题目大意&#xff1a; 在一个三维空间当中&#xff0c;每次进行一个操作&#xff0c;添加一个点或者统计空间中的某一个长方体范围内的所有点 三维空间中我们用两个点即可确定一个长方体。 首先效仿平面二维数点的方法&#xff0c;根据容斥原理可以把询问拆分成8个以原点…

[翻译] C# 8.0 新特性

原文: Building C# 8.0[译注:原文主标题如此&#xff0c;但内容大部分为新特性介绍&#xff0c;所以意译标题为 "C# 8.0 新特性"]C# 的下一个主要版本是 8.0。我们已经为它工作了很长一段时间&#xff0c;即使我们构建并发布了次要版本 C# 7.1, 7.2 和 7.3&#xff0…

[蓝桥杯][2018年第九届真题]搭积木

[[蓝桥杯][2018年第九届真题]搭积木](https://www.dotcpp.com/oj/problem2292.html)题目&#xff1a; 小明对搭积木非常感兴趣。他的积木都是同样大小的正立方体。 在搭积木时&#xff0c;小明选取 m 块积木作为地基&#xff0c;将他们在桌子上一字排开&#xff0c;中间不留空…

NOI.AC#2007-light【根号分治】

正题 题目链接:http://noi.ac/problem/2007 题目大意 nnn个格子排成一排&#xff0c;每个格子有一个0/10/10/1和一个颜色。开始每个格子都是000&#xff0c;qqq次操作取反一个颜色的所有格子的0/10/10/1&#xff0c;然后询问111的格子构成的连通块数量。 1≤n,q≤1051\leq n,q…

【招聘(广州)】 招聘.NET程序员

招聘&#xff1a;.NET程序员工作地点&#xff1a;广州天河区CBD&#xff08;地铁3号线珠江新城站&#xff09;职位描述&#xff1a;网站平台、移动页面、APP、微信小程序、接口等开发&#xff1b;与UI/UX&#xff0c;设计师、产品经理偕同工作一起排查、定位、优化产品性能。任…

【模板】一维树状数组

ACM模板 目录聊聊前缀和什么是树状数组?树状数组相关操作局限性差分在树状数组中的应用区间更新、单点查询区间更新、区间查询树状数组应用聊聊前缀和 比如数组 int a[7]{1,2,3,4,5,6,7}如果需询问数组从第l个数到第r个数的和暴力做法时间复杂度为O(n)O(n)O(n) 不过我们可以…

牛客题霸 单链表的选择排序 C++题解/答案

牛客题霸 单链表的选择排序 C题解/答案 题目描述 给定一个无序单链表&#xff0c;实现单链表的选择排序(按升序排序)。 题解&#xff1a; 不可能手写排序&#xff0c;这辈子不可能手写排序。。 基础的链表操作&#xff0c;将链表内的数据存到vector内&#xff0c;然后用sor…

牛客练习赛71E-神奇的迷宫【点分治,NTT】

正题 题目链接:https://ac.nowcoder.com/acm/contest/7745/E 题目大意 给出nnn个点的一棵树&#xff0c;每个点有一个选择权重aia_iai​&#xff08;有ai∑i1nai\frac{a_i}{\sum_{i1}^na_i}∑i1n​ai​ai​​的概率被选择&#xff09;。 然后有一个序列www。随机选择两次点&…

使用C#把Tensorflow训练的.pb文件用在生产环境

训练了很久的Tf模型&#xff0c;终于要到生产环境中去考验一番了。今天花费了一些时间去研究tf的模型如何在生产环境中去使用。大概整理了这些方法。继续使用分步骤保存了的ckpt文件这个貌似脱离不了tensorflow框架&#xff0c;而且生成的ckpt文件比较大&#xff0c;发布到生产…

OpenJudge1043 树上游戏(换根dp+细节处理)

树上游戏 给定一棵 nnn 个节点的树&#xff0c;点从 111 到 nnn 编号&#xff0c;点有点权&#xff0c;边有边权&#xff0c; Alice\text{Alice}Alice 和 Bob\text{Bob}Bob 两人在做游戏。 棋子以某一个点 sss 为起点&#xff0c;玩家移动该棋子&#xff0c;有以下两条规则&a…