题目: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. orb slam2

  2. sql常用手法(二)

    drop,TRUNCATE和delete的区别 1.DROP删表,表结构将删了,当然数据也不存在了2.TRUNCATE和DELETE删数据,表结构还在3.DELETE可以带条件删除,TRUNCATE是 ...

  3. 「 HDU P3555 」 Bomb

    # 题目大意 给出 $\text{T}$ 个数,求 $[1,n]$ 中含 ‘49’ 的数的个数. # 解题思路 求出不含 '49' 的数的个数,用总数减去就是答案. 数位 $DP$,用记忆化来做. 设 ...

  4. 微信小程序中如何实现分页下拉加载?(附源码)

    转眼间坚持写教你微信小程序系列已经有十节系列课程了,每天的工作压力繁重,小女子也不知道自己还能坚持这样的系列教程多久.只希望每篇教程真的对大家有帮助.这节课我们要介绍的就是如何实现分页的下拉加载,我们 ...

  5. Hashing - Hard Version

    Hashing - Hard Version Given a hash table of size N, we can define a hash function . Suppose that th ...

  6. 【codeforces 709B】Checkpoints

    [题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...

  7. BNUOJ 33895 D-City

    D-City Time Limit: 1000ms Memory Limit: 65535KB This problem will be judged on HDU. Original ID: 449 ...

  8. Ubuntu 16.04使用NASM编译时用ld链接程序出现:i386 架构于输入文件 sandbox.o 与 i386:x86-64 输出不兼容(I386 architecture in the input file sandbox.o is not compatible with i386: x86-64 output)

    错误: 问题解决过程: 1.先确定CPU的架构 2.这是以64位架构的CPU,如果使用elf参数时,默认是以32位模式去处理,那么此时需要更精确的去指定这个模式,比如elf32(32位),elf64( ...

  9. vue2源码浏览分析01

    1.构造函数  Vue$3 function Vue$3 (options) { if ("development" !== 'production' && !(t ...

  10. ubuntu 安装 swift

    第一步 安装mysql和mysql的python支持 apt-get install python-mysqldb mysql-server 第二步 配置mysql vim /etc/mysql/my ...