题目: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. Codeforces 280C - Game on Tree

    传送门:280C - Game on Tree 不知道期望是啥的请自行Baidu或Google,(溜了 题目大意,有一棵有根树,每次随机选择一个节点,将这个节点和它的子树删除,问将整棵树删除的期望次数 ...

  2. APUE 文件IO

    文件 IO 记录书中的重要知识和思考实践部分 Unix 每个文件都对应一个文件描述符(file descriptor),为一个非负整数,一个文件可以有多个fd, 后面所有与文件(设备,套接字等)有关操 ...

  3. Code128条形码如何计算其宽度?如何得出其校验位?

    原文链接 Code128条形码是一个非常高密的字母数字条码,能够存储需要的编码数据,它可以编码所有128个ASCII码字符,它使用最少的空间. 在Code128符号体系中,每个数据字符编码都是由11个 ...

  4. python json、 pickle 、shelve 模块

    json 模块 用于序列化的模块 json,用于字符串 和 python数据类型间进行转换 Json模块提供了四个功能:dumps.dump.loads.load #!/usr/bin/env pyt ...

  5. lucas定理和组合数学

    自湖南长沙培训以来的坑...一直未填,今天把这个问题解决掉. 参考: 1.http://www.cnblogs.com/Var123/p/5523068.html 2.http://blog.csdn ...

  6. 【Codeforces 348A】Mafia

    [链接] 我是链接,点我呀:) [题意] 每轮游戏都要有一个人当裁判,其余n-1个人当玩家 给出每个人想当玩家的次数ai 请你求出所需要最少的玩游戏的轮数 使得每个人都能满足他们当玩家的要求. [题解 ...

  7. 分析helo1项目中的 Web.xml

    web.xml文件位于hello1 中target/WEB-INF/classes/javaeetutorial目录下. 这个web.xml文件包含Facelets应用程序所需的几个元素: 其中(1) ...

  8. java ee开发常用类和接口

    1.javax.Validation接口,做mvc传入数据验证用 2.javax.servlet接口 3.javax.datasource接口 4.javax.session接口 5.javax.ht ...

  9. java NPE就是空指针异常,null pointer exception

    java NPE就是空指针异常,null pointer exception

  10. nodejs fs.open

    fs.open(path, flags, [mode], [callback(err, fd)])是 POSIX open 函数的封装,与 C 语言标准库中的 fopen 函数类似.它接受两个必选参数 ...