传送门

本来想用点分治做,结果root又求不对 算的时候还算错了 我好菜啊

结果szr大佬告诉我是树形dp

我好菜啊!!

我们有$\lceil \frac{x}{k} \rceil = \frac{x+(k-x)\%k}{k}$

于是可以把这个拆成两部分来求,最后加在一起再除个k

距离和很好求,连接x和fa[x]的边的贡献就是$size[x]*(N-size[x])$

然后考虑到k很小,我们可以直接记x的子树中到x距离%k=y的个数f[x][y],然后拿这个去算

 #pragma GCC optimize(3)
#include<bits/stdc++.h>
#define pa pair<ll,ll>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=1e5+,maxk=; inline char gc(){
return getchar();
static const int maxs=<<;static char buf[maxs],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,maxs,stdin),p1==p2)?EOF:*p1++;
}
inline ll rd(){
ll x=;char c=gc();bool neg=;
while(c<''||c>''){if(c=='-') neg=;c=gc();}
while(c>=''&&c<='') x=(x<<)+(x<<)+c-'',c=gc();
return neg?(~x+):x;
} int eg[maxn*][],egh[maxn],ect=;
int N,K,siz[maxn],dcnt[maxk],smsiz,fa[maxn];
ll ans;
bool flag[maxn]; inline void adeg(int a,int b,int c){
eg[++ect][]=b,eg[ect][]=c,eg[ect][]=egh[a],egh[a]=ect;
} void getroot(int x,int f,int &rt,int &mis){
siz[x]=;
int mm=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==f||flag[b]) continue;
fa[b]=x;getroot(b,x,rt,mis);
siz[x]+=siz[b];mm=max(mm,siz[b]);
}
mm=max(mm,smsiz-siz[x]);
if(mm<mis) rt=x,mis=mm;
} void getdis(int x,int f,int d){
dcnt[d]++;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==f||flag[b]) continue;
getdis(b,x,(d+eg[i][])%K);
}
} inline ll calc(int x,int ini){
ll re=;
CLR(dcnt,);getdis(x,,ini);
for(int i=;i<K;i++){
for(int j=i+;j<K;j++){
re+=1ll*dcnt[i]*dcnt[j]*((K+(K-i-j)%K)%K);
}
}
for(int i=;i<K;i++) re+=1ll*dcnt[i]*(dcnt[i]-)/*((K+(K-i-i)%K)%K);
return re;
} void solve(int x){
flag[x]=;
ans+=calc(x,);
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(flag[b]) continue;
ans-=calc(b,eg[i][]%K);
int rt=,mis=1e9;smsiz=siz[b];
getroot(b,,rt,mis);
siz[fa[rt]]=smsiz-siz[rt];
solve(rt);
}
} void dfs(int x,int f){
siz[x]=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==f) continue;
dfs(b,x);siz[x]+=siz[b];
ans+=1ll*siz[b]*(N-siz[b])*eg[i][];
}
} int main(){
// freopen("t3.in","r",stdin);
// freopen("t3.out","w",stdout);
int i,j,k;
N=rd(),K=rd();
for(i=;i<N;i++){
int a=rd(),b=rd(),c=rd();
adeg(a,b,c);adeg(b,a,c);
}
smsiz=N;int mis=1e9,rt=;
getroot(,,rt,mis);
solve(rt);
dfs(,);
printf("%lld\n",ans/K);
return ;
}

ZZ点分治

 #include<bits/stdc++.h>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
const int maxn=1e5+,maxk=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int eg[maxn*][],egh[maxn],ect;
int dp[maxn][maxk],siz[maxn];
int N,K;
ll ans; inline void adeg(int a,int b,int c){
eg[++ect][]=b,eg[ect][]=c,eg[ect][]=egh[a],egh[a]=ect;
} inline void dfs(int x,int f){
siz[x]=;dp[x][]=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==f) continue;
dfs(b,x);siz[x]+=siz[b];
ans+=1ll*eg[i][]*(N-siz[b])*siz[b];
for(int j=;j<K;j++)
for(int k=;k<K;k++)
ans+=1ll*((K+(-(j+eg[i][])%K-k)%K)%K)*dp[b][j]*dp[x][k];
for(int j=;j<K;j++)
dp[x][(j+eg[i][])%K]+=dp[b][j];
}
} int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd(),K=rd();
for(i=;i<N;i++){
int a=rd(),b=rd(),c=rd();
adeg(a,b,c);adeg(b,a,c);
}
dfs(,);
printf("%lld\n",ans/K);
return ;
}

noiac132 B君的第三题 (树形dp)的更多相关文章

  1. test20181016 B君的第三题

    题意 B 君的第三题(haskell) 题目描述 大学四年,我为什么,为什么不好好读书,没找到和你一样的工作. B 君某天看到了这样一个题,勾起了无穷的回忆. 输入\(n, k\) 和一棵\(n\) ...

  2. test20181015 B 君的第三题

    题意 B 君的第三题(zhengzhou) 题目描述 让你在战争和耻辱中做一块选择,你选择耻辱,可你将来还得进行战争. 在平面上有n 个整点(横纵坐标都是整数) B 君想找到一个整点,使得这个点,到所 ...

  3. test20181018 B君的第三题

    题意 B 君的第三题(shenyang) 题目描述 客似云来,万里无云 B 君得到了一个数组\(\{a_1,a_2,\dots,a_n\}\). B 君想通过修改让数组中个每对数都互质. 每次使一个数 ...

  4. test20181019 B君的第三题

    题意 B 君的第三题(urumqi) 题目描述 风雨如晦,鸡鸣不已. B 君最近在研究自己的学长都在做什么工作,每个学长属于一个公司. B 君会获得一些信息,比如x 和y 在相同公司,x 和y 在不同 ...

  5. POJ-3659-最小支配集裸题/树形dp

    Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7127   Accepted: 254 ...

  6. 加分二叉树 vijos1991 NOIP2003第三题 区间DP/树形DP/记忆化搜索

    描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一 ...

  7. HDU 4679 Terrorist’s destroy (2013多校8 1004题 树形DP)

    Terrorist’s destroy Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  8. 【uva1380 - 一个调度问题】思路题+树形dp

    [题意] 有n<=200个恰好需要一天完成的任务,要求用最少的时间完成所有任务.任务可以同时完成.但是有一些约束,分有向和无向两种,其中A-->B表示A必须在B前面完成,而A--B表示A和 ...

  9. 【DP_树形DP专题】题单总结

    转载自 http://blog.csdn.net/woshi250hua/article/details/7644959#t2 题单:http://vjudge.net/contest/123963# ...

随机推荐

  1. 08-webpack的介绍

    在这里我仅仅的是对webpack做个讲解,webpack这个工具非常强大,解决了我们前端很繁琐的一些工具流程繁琐的事情.如果感兴趣的同学,简易还是看官网吧. 中文链接地址:https://www.we ...

  2. php之常用扩展总结

    在此总结,开发中经常使用到的扩展,来进行日常PHP的开发工作 bcmath(精确数值处理) bz2 calendar Core ctype curl date dom ereg exif filein ...

  3. MySQL索引的设计、使用和优化

    原文:http://bbs.landingbj.com/t-0-243071-1.html MySQL索引概述 所有MySQL列类型可以被索引.对相关列使用索引是提高SELECT操作性能的最佳途径.根 ...

  4. python3 selenium webdriver 元素定位xpath定位骚操作

    源文http://www.cnblogs.com/qingchunjun/p/4208159.html By.xpath() 这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元 ...

  5. Python Note1: Pycharm的安装与使用

    前言 曾经学过一段时间python,虽然现在工作了主要使用C#和C++,但是觉得还是有必要在业余的时候学习学习python,提升下自己的知识面,毕竟技多不压身,加油吧! 安装与激活Pycharm 个人 ...

  6. centos7系统管理和运维实战——运维必备的网络管理技能(1)

    运维必备的网络管理技能 一.网络管理协议: 1.简单的两个概念:    DHCP(动态主机配置协议):如果网络结构要更改,需要从新初始化网络参数,手机用动态主机配置协议可以避免这个问题.客户端可以从D ...

  7. centos安装Tesseract

    yum安装(推荐) yum search tesseract yum install tesseract.x86_64 -y pip3 install pytesseract pip3 install ...

  8. 用dbexpress连接sqlserver数据库

    SQLConnection1.Params.clearSQLConnection1.Params.Values['ServerName'] := '192.168.0.112'; SQLConnect ...

  9. java 中 Math类

    package cn.liuliu.com; import java.math.BigDecimal; import java.math.BigInteger; /* * 一.Math类? * * 1 ...

  10. 二、启用Docker支持

    一.使用