正题

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


题目大意

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

1≤T≤5,1≤n≤2999951\leq T\leq 5,1\leq n\leq 2999951≤T≤5,1≤n≤299995


解题思路

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

随便以一个点为根的话,对于一个点,割掉它子树外面的一条边,设割去的连通块大小为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(n−k−sx​)≤n−S2fx​≤n−k​
移一下项就有
n−2sx≤k≤n−2fxn-2s_x\leq k\leq n-2f_xn−2sx​≤k≤n−2fx​

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

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

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

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

如果不考虑不在子树内的话挺好搞,对于根节点到该节点的路径都是n−sizxn-siz_xn−sizx​,否则是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;
}

P5666-[CSP-S2019]树的重心【树状数组】相关推荐

  1. poj 1655 树的重心 define注意事项

    http://blog.csdn.net/acdreamers/article/details/16905653 题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果 ...

  2. 树的直径,树的中心,树的重心

    树的直径,树的中心,树的重心 树的直径:树上两点间最长距离所对应的路径 求法一:树形dp: 从每个点向下搜索,找到以该点为根到子节点的最大值和次大值 然后将次大值和最大值相加,即求得经过该点的最长路径 ...

  3. acwing 846. 树的重心

    给定一颗树,树中包含 n 个结点(编号 1∼n)和 n−1 条无向边. 请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值. 重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余 ...

  4. CSP2019洛谷P5666:树的重心

    解析 毒题 细节有亿点点多 我一开始的思路是没有问题的 尝试统计有多少种方案能砍出大小在一个区间的子树. 当时的想法是线段树合并 但是这个玩意在需要保留原树的情况下空间复杂度炸没了- 因为我垃圾的实现 ...

  5. 好骚气的树状数组的解释

    引用请注明出处:http://blog.csdn.net/int64ago/article/details/7429868 写下这个标题,其实心里还是没底的,与其说是写博帖,不如说是做总结.第一个接触 ...

  6. 【BZOJ-3730】震波 动态点分治 + 树状数组

    3730: 震波 Time Limit: 15 Sec  Memory Limit: 256 MB Submit: 626  Solved: 149 [Submit][Status][Discuss] ...

  7. UOJ276 [清华集训2016] 汽水 【二分答案】【点分治】【树状数组】

    题目分析: 这种乱七八糟的题目一看就是点分治,答案有单调性,所以还可以二分答案. 我们每次二分的时候考虑答案会不会大于等于某个值,注意到系数$k$是无意义的,因为我们可以通过转化使得$k=0$. 合并 ...

  8. 2023牛客寒假算法基础集训营4_20230130「向上取整」「夹逼dp」「lowbit科学+树状数组性质」「搜索」「倍增跳表」「莫队」

    6/13 教育场是有被教育到.(预计会鸽几题. 已过非太水的题们 //B //https://ac.nowcoder.com/acm/contest/46812/B//小构造小数学#include & ...

  9. 洛谷 P5057 [CQOI2006]简单题(树状数组)

    嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...

最新文章

  1. R语言进行dataframe数据内连接(Inner join):使用R原生方法、data.table、dplyr等方案
  2. 1067 Sort with Swap(0, i) (25 分)【难度: 中 / 知识点: 置换群】
  3. python爬虫课件_Python爬虫教学视频(附课件)
  4. Mysql5.X重点难点速记
  5. php中英文截取字符串长度,PHP截取字符串长度(中英文混合字符串)_PHP教程
  6. windows查看java进程详细信息的几种方法
  7. (LINQ 学习系列)(8)Linq教程实例: 事务处理
  8. 线程池的开源实现(mariadb和percona版本)
  9. Vue插槽(solt)简单案例
  10. python 加汉明窗_什么是汉明窗?加Hanmming窗的作用?
  11. ip自签名ssl证书
  12. 分享下我 Github 被封的经历
  13. 加推科技领读:2019,深圳开荒牛的TO B拓荒路
  14. Kanban in Action 免积分下载
  15. visio常用快捷键_Visio快捷键
  16. Spring AOP拦截规则的两种定义方式
  17. 谷歌地图地理翻遍码,谷歌地图地点搜索
  18. 罗克韦尔自动化收购MESTECH Services
  19. JavaScript:使用Canvas绘图
  20. Ubuntu重启后如何配置网络

热门文章

  1. url采集工具_大数据关键技术浅谈之大数据采集
  2. mendelay为什么安装不了_你为什么消防验收过不了?消防管道安装错误图集
  3. android tabhost黑色背景,android更改FragmentTabHost背景和文本颜色
  4. 【解决bug之路】JAVA 之 static
  5. 服务器精益改善系列,精益生产改善的内容是什么?
  6. lighttpd mysql_lighttpd+mysql+php
  7. 在idae中为什么用Module创建一个新的Maven项目的时候会被卡死
  8. DEBUG org.springframework.web.servlet.DispatcherServlet - Error rendering view [org.thymeleaf.spring
  9. [C++11]函数模板的默认模板参数
  10. 2-SAT适定性(Satisfiability)问题知识点详解