题目:https://www.luogu.org/problemnew/show/P2634

今天刚学了点分治,做例题;

好不容易A了,结果发现自己写的是树形DP...(也不用找重心)(比点分治快)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=,inf=0x3f3f3f3f;
int n,hd[maxn],ct,siz[maxn],mx,rt;
ll cnt[maxn][],ans,tot,tmp[];
struct N{
int to,nxt,w;
N(int t=,int n=,int w=):to(t),nxt(n),w(w) {}
}ed[maxn<<];
void add(int x,int y,int z){ed[++ct]=N(y,hd[x],z); hd[x]=ct;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void dfs(int x,int fa)
{
siz[x]=; int nmx=;
for(int i=hd[x],u;i;i=ed[i].nxt)
{
if((u=ed[i].to)==fa)continue;
dfs(u,x); siz[x]+=siz[u];
nmx=max(nmx,siz[u]);
}
nmx=max(nmx,n-siz[x]);
if(nmx<mx)rt=x,mx=nmx;//mx=nmx!!
}
void work(int x,int fa)
{
cnt[x][]=;
for(int i=hd[x],u;i;i=ed[i].nxt)
{
if((u=ed[i].to)==fa)continue;
work(u,x);
for(int j=;j<=;j++)tmp[j]=cnt[u][((j-ed[i].w)%+)%];
ans+=cnt[x][]*tmp[];
ans+=cnt[x][]*tmp[];
ans+=cnt[x][]*tmp[];
for(int j=;j<=;j++)cnt[x][j]+=tmp[j];
}
// ans+=cnt[x][0];//
// ans++;
}
int main()
{
// freopen("test.txt","r",stdin);
scanf("%d",&n); mx=inf;
for(int i=,x,y,z;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
dfs(,); work(rt,);
ans=ans*+n; tot=(ll)n*n;
ll g=gcd(ans,tot);
printf("%lld/%lld\n",ans/g,tot/g);
return ;
} 树形DP

树形DP

点分治是先算出经过根的,再去掉根,对于子树进行相同的操作,还要容斥掉刚才算上的、经过该子树根节点的答案。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=,inf=0x3f3f3f3f;
int n,hd[maxn],ct,siz[maxn],mx,rt,sum,dep[maxn];
ll cnt[maxn][],ans,tot,tmp[];
bool vis[maxn];
struct N{
int to,nxt,w;
N(int t=,int n=,int w=):to(t),nxt(n),w(w) {}
}ed[maxn<<];
void add(int x,int y,int z){ed[++ct]=N(y,hd[x],z); hd[x]=ct;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void dfs(int x,int fa)
{
siz[x]=; int nmx=;
for(int i=hd[x],u;i;i=ed[i].nxt)
{
if((u=ed[i].to)==fa||vis[u])continue;
dfs(u,x); siz[x]+=siz[u];
nmx=max(nmx,siz[u]);
}
nmx=max(nmx,sum-siz[x]);
if(nmx<mx)rt=x,mx=nmx;//mx=nmx!!
}
void getdep(int x,int fa)
{
tmp[dep[x]%=]++;
for(int i=hd[x],u;i;i=ed[i].nxt)
{
if((u=ed[i].to)==fa||vis[u])continue;
dep[u]=dep[x]+ed[i].w;
getdep(u,x);
}
}
ll calc(int x,int v)
{
dep[x]=v; tmp[]=tmp[]=tmp[]=;
getdep(x,);//0
return tmp[]*tmp[]+tmp[]*tmp[]*;
}
void work(int x)
{
ans+=calc(x,); vis[x]=;
for(int i=hd[x],u;i;i=ed[i].nxt)
{
if(vis[u=ed[i].to])continue;
ans-=calc(u,ed[i].w);
mx=inf; sum=siz[u]; dfs(u,);
work(rt);
}
}
int main()
{
// freopen("test.txt","r",stdin);
scanf("%d",&n);
for(int i=,x,y,z;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
mx=inf; sum=n; dfs(,); work(rt);
tot=(ll)n*n;
ll g=gcd(ans,tot);
printf("%lld/%lld\n",ans/g,tot/g);
return ;
}

洛谷 P2634 聪聪可可 —— 树形DP / 点分治的更多相关文章

  1. 洛谷 P3177 [HAOI2015]树上染色 树形DP

    洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...

  2. 洛谷 P2634 BZOJ 2152 【模板】点分治(聪聪可可)

    题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...

  3. 洛谷P1040 加分二叉树(树形dp)

    加分二叉树 时间限制: 1 Sec  内存限制: 125 MB提交: 11  解决: 7 题目描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,...,n),其中数字1,2,3,...,n ...

  4. 洛谷P4438 道路 [HNOI/AHOI2018] 树形dp

    正解:树形dp 解题报告: 传送门! 昂首先看懂题目趴QwQ大概就是说有棵满二叉树,有n个叶子节点(乡村)和n-1个非叶子节点,然后这棵树的每个节点有三个属性abc,对每个非叶子节点可以从与子节点的两 ...

  5. 洛谷 P4201 设计路线 [NOI2008] 树形dp

    正解:树形dp 解题报告: 大概是第一道NOI的题目?有点激动嘻嘻 然后先放个传送门 先大概港下这题的题意是啥qwq 大概就是给一棵树,然后可以选若干条链把链上的所有边的边权变成0,但是这些链不能有交 ...

  6. 洛谷 P3267 [JLOI2016/SHOI2016]侦察守卫(树形dp)

    题面 luogu 题解 树形\(dp\) \(f[x][y]表示x的y层以下的所有点都已经覆盖完,还需要覆盖上面的y层的最小代价.\) \(g[x][y]表示x子树中所有点都已经覆盖完,并且x还能向上 ...

  7. 洛谷P1351 联合权值(树形dp)

    题意 题目链接 Sol 一道很简单的树形dp,然而被我写的这么长 分别记录下距离为\(1/2\)的点数,权值和,最大值.以及相邻儿子之间的贡献. 树形dp一波.. #include<bits/s ...

  8. 洛谷P4099 [HEOI2013]SAO(树形dp)

    传送门 HEOI的题好珂怕啊(各种意义上) 然后考虑树形dp,以大于为例 设$f[i][j]$表示$i$这个节点在子树中排名第$j$位时的总方案数(因为实际只与相对大小有关,与实际数值无关) 我们考虑 ...

  9. 洛谷 P1351 联合权值 —— 树形DP

    题目:https://www.luogu.org/problemnew/show/P1351 树形DP,别忘了子树之间的情况(拐一下距离为2). 代码如下: #include<iostream& ...

随机推荐

  1. vue项目 build之后发布到服务器index.html页面空白解决方法

    第一部分 之前一直不太理解为什么要使用vue+webapck,还有在使用了vue-cli之后会用到后台,即vue-cli自动帮我们安装了express服务器,在本地服务器上运行,因为我们希望可以模拟在 ...

  2. vue基础---条件渲染

    (1)v-if条件渲染 v-if 指令用于条件性地渲染一块内容.这块内容只会在指令的表达式返回 truthy 值的时候被渲染. 可以用 v-else 添加一个“else 块”: ①表达式 <di ...

  3. 微服务网关从零搭建——(九)网关部署到linux服务器

    环境准备 公司电脑已安装core环境所以此处略过core环境安装 可参看此处 consul安装 如果没有wget命令 执行以下命令 yum install wget 下载consul wget htt ...

  4. 面向对象程序设计--Java语言第三周编程题:查找里程

    查找里程 题目内容: 下图为国内主要城市之间的公路里程: 你的程序要读入这样的一张表,然后,根据输入的两个城市的名称,给出这两个城市之间的里程. 注意:任何两个城市之间的里程都已经给出,不需要计算经第 ...

  5. 数组--P1980 计数问题

    题目描述 题解 试计算在区间 1 到 n的所有整数中,数字 x(0 ≤ x ≤ 9)共出现了多少次?例如,在 1到 11中,即在 1,2,3,4,5,6,7,8,9,10,11 中,数字 1 出现了 ...

  6. jieba的基本使用

    目录 1.分词 2.添加自定义词典 3.关键词提取 4.词性标注 jieba 是一款优秀的 Python 第三方中文分词库,可以使用 pip install jieba / pip3 install ...

  7. Servlet的说明及使用案例

    Servlet的说明及使用案例 制作人:全心全意 Servle的基础介绍 Servlet结构体系 Servlet对象.ServletConfig对象与Serializable对象是接口对象,其中Ser ...

  8. 通过response对象的sendRedirect方法重定向网页

    通过response对象的sendRedirect方法重定向网页 制作人:全心全意 使用response对象提供的sendRedirect()方法可以将网页重定向到另一个页面.重定向操作支持将地址重定 ...

  9. 55. spring boot 服务配置和部署【从零开始学Spring Boot】

    Spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat).当然你也可以将项 ...

  10. 初次使用Let's encrypt

    wget --no-check-certificate -O shadowsocks.sh https://raw.githubusercontent.com/teddysun/shadowsocks ...