当前位置: 首页 > news >正文

CF1060E Sergey and Subway(点分治)

给出一颗$N$个节点的树,现在我们**在原图中**每个不直接连边但是中间只间隔一个点的两个点之间连一条边. 比如**在原图中**$u$与$v$连边,$v$与$w$连边,但是$u$与$w$不连边,这时候我们就需要连一条$u$与$v$的边. 现在我们需要求出新图中每一个点对$(i,j)\ (1 \leq i \leq j \leq N)$的经过的边数和.

 

因为实在太菜了不会树形dp的只好用点分了……

(点分是个好东西所有树的题目都可以暴力艹过去)

首先,设原点对之间距离为$dis$,如果$dis$是奇数,那么新的距离为$(dis>>1)+1$,否则为$dis>>1$

我们考虑如何计算经过当前根节点的路径对答案的贡献

我们设已经dfs过的子树中有$cnt0$条长度为偶数的链,$dis0$这些链的每一条的长度除以二之和,同理$cnt1$和$dis1$表示长度为奇数的链的条数和每一条链的长度除以二加一的和

简单来讲$dis1$和$dis0$分别表示将原$dis$按上面的方法转化后的答案

然后考虑当前子树$v$,设$v$中的以上信息分别为,$cnt[0],cnt[1],dis[0],dis[1]$

然后就是路径的两两组合分别计入答案就是了

顺便注意因为两条奇数路径合起来变为偶数,所以相当于每一条路径的长度都要减一

然后别忘了加上子树单独的贡献

 1 //minamoto
 2 #include<bits/stdc++.h>
 3 #define ll long long
 4 using namespace std;
 5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 6 char buf[1<<21],*p1=buf,*p2=buf;
 7 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
 8 inline int read(){
 9     #define num ch-'0'
10     char ch;bool flag=0;int res;
11     while(!isdigit(ch=getc()))
12     (ch=='-')&&(flag=true);
13     for(res=num;isdigit(ch=getc());res=res*10+num);
14     (flag)&&(res=-res);
15     #undef num
16     return res;
17 }
18 const int N=2e5+5;
19 int head[N],Next[N<<1],ver[N<<1],tot;
20 int cnt[2];ll dis[2],ans=0;
21 inline void add(int u,int v){
22     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
23 }
24 int sz[N],son[N],size,vis[N],rt,n;
25 void findrt(int u,int fa){
26     sz[u]=1,son[u]=0;
27     for(int i=head[u];i;i=Next[i]){
28         int v=ver[i];
29         if(vis[v]||v==fa) continue;
30         findrt(v,u),sz[u]+=sz[v],cmax(son[u],sz[v]);
31     }
32     cmax(son[u],size-sz[u]);
33     if(son[u]<son[rt]) rt=u;
34 }
35 void dfs(int u,int fa,int d){
36     d&1?(++cnt[1],dis[1]+=((d>>1)+1)):(++cnt[0],dis[0]+=(d>>1));
37     for(int i=head[u];i;i=Next[i]){
38         int v=ver[i];
39         if(v!=fa&&!vis[v]) dfs(v,u,d+1);
40     }
41 }
42 void getans(int u){
43     int cnt0=0,cnt1=0;ll dis0=0,dis1=0;
44     for(int i=head[u];i;i=Next[i]){
45         int v=ver[i];
46         if(vis[v]) continue;
47         cnt[0]=cnt[1]=0,dis[0]=dis[1]=0;
48         dfs(v,u,1);
49 //        ans+=dis[1]*dis1-cnt[1]*cnt1;
50 //        ans+=dis[1]*dis0;
51 //        ans+=dis[0]*dis1;
52 //        ans+=dis[0]*dis0;
53         ans+=dis[1]*cnt1+dis1*cnt[1]-1ll*cnt1*cnt[1];
54         ans+=dis[1]*cnt0+dis0*cnt[1];
55         ans+=dis[0]*cnt1+dis1*cnt[0];
56         ans+=dis[0]*cnt0+dis0*cnt[0];
57         ans+=dis[1]+dis[0];
58         cnt0+=cnt[0],cnt1+=cnt[1];
59         dis0+=dis[0],dis1+=dis[1];
60     }
61 }
62 void solve(int u){
63     vis[u]=1,getans(u);
64     for(int i=head[u];i;i=Next[i]){
65         int v=ver[i];
66         if(vis[v]) continue;
67         size=sz[v],rt=0,findrt(v,u);
68         solve(rt);
69     }
70 }
71 int main(){
72 //    freopen("testdata.in","r",stdin);
73     n=read();
74     for(int i=1,u,v;i<n;++i)
75     u=read(),v=read(),add(u,v),add(v,u);
76     son[rt=0]=n+1,size=n,findrt(1,0);
77     solve(rt);
78     printf("%I64d\n",ans);
79     return 0;
80 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9767144.html

相关文章:

  • CentOS 7更改yum源与更新系统
  • Python基本数据类型集合、格式化、函数
  • 印章与合同管理一体化:杜绝实体印章与纸质合同隐患
  • 微软正式发布Azure Functions 2.0
  • 微信小程序所带来的机会
  • CLTPHP5.0发布
  • 支付宝小程序
  • 23、【支付模块开发】——Java对接支付宝步骤(沙箱环境)
  • karabiner json语法
  • Java反射-动态类加载和重新加载
  • 女博士被程序员嘲笑:代码能力太差,不知道怎么招进来的
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • WordCount2.0
  • 用阿里云函数计算部署thinkphp5.1
  • 01什么是面向对象,面向对象的基本操作
  • python3.6+scrapy+mysql 爬虫实战
  • angular组件开发
  • ES6系统学习----从Apollo Client看解构赋值
  • JavaScript对象详解
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Objective-C 中关联引用的概念
  • Python爬虫--- 1.3 BS4库的解析器
  • vue总结
  • 复习Javascript专题(四):js中的深浅拷贝
  • 搞机器学习要哪些技能
  • 回顾2016
  • 区块链技术特点之去中心化特性
  • 如何选择开源的机器学习框架?
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 手机端车牌号码键盘的vue组件
  • 《天龙八部3D》Unity技术方案揭秘
  • ​520就是要宠粉,你的心头书我买单
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • #QT(一种朴素的计算器实现方法)
  • (C++)八皇后问题
  • (分类)KNN算法- 参数调优
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (十五)使用Nexus创建Maven私服
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • .Net core 6.0 升8.0
  • .net framework 4.0中如何 输出 form 的name属性。
  • .NET Micro Framework初体验
  • .NET 设计模式初探
  • .net和php怎么连接,php和apache之间如何连接
  • .net快速开发框架源码分享
  • .pyc文件是什么?
  • @reference注解_Dubbo配置参考手册之dubbo:reference
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [17]JAVAEE-HTTP协议
  • [Android 13]Input系列--获取触摸窗口
  • [Android]RecyclerView添加HeaderView出现宽度问题
  • [Angular] 笔记 18:Angular Router
  • [JavaWeb玩耍日记]Maven的安装与使用
  • [LeetCode] 196. 删除重复的电子邮箱