test20181016 B君的第三题

题意

B 君的第三题(haskell)

题目描述

大学四年,我为什么,为什么不好好读书,没找到和你一样的工作。

B 君某天看到了这样一个题,勾起了无穷的回忆。

输入\(n, k\) 和一棵\(n\) 个点的树,有边权,没有点权。两点\(i, j\) 之间的距离\(D(i, j)\) 定义为路径上的边权和。求

\[
\sum_{1 \leq i < j \leq n} \left\lceil \frac{D(i,j)}{k} \right\rceil
\]

换句话说,枚举无序的两个点,求出距离除以\(k\) 上取整的和。

输入格式

输入第一行包含两个整数\(n, k\)。

接下来\(n-1\) 行,每行三个整数\(x, y, z\),表示\(x\) 和\(y\) 之间有一条边,边权为\(z\)。

输出格式

输出一行一个整数,表示答案。

样例输入

4 6

1 2 2

1 3 3

1 4 4

样例输出

7

数据规模与约定

对于100% 的数据,满足\(1 \leq n \leq 100000, 1 \leq k \leq 10\)。

对于100% 的数据,满足\(1 \leq x, y \leq n, 1 \leq z \leq 10\)。

对于30% 的数据,满足\(n \leq 1000\)。

对于另20% 的数据,满足\(k = 1\)。

对于另20% 的数据,满足\(k = 2\)。

分析

先考虑没有取整的情况,是一个经典题。

然后考虑有多少条路径模 k 余 1, 2, . . .。

这题是NOI2011道路修建和BZOJ2152聪聪可可改编而成的一道好题。

\[
\lceil \frac{x}{k} \rceil = \frac{x + k - x \mod{k}}{k}
\]

所以我们需要求出分别有多少路径模k等于1,2,..k-1。

考虑dp。

用\(f(i,j)\)表示i的子树中有多少点到i的距离mod k = j,\(c(i)\)表示全局有多少路径mod k = i。

f、c都能在dfs的时候求出,注意顺序,不能用子树乘自己本身的方案。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#define rg register
#define il inline
#define co const
#pragma GCC optimize ("O0")
using namespace std;
template<class T> il T read(rg T&x)
{
    rg T data=0;
    rg int w=1;
    rg char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==‘-‘)
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-‘0‘,ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

const int MAXN=1e5+7,MAXK=11;
int n,k;

struct Edge
{
    int nx,to,w;
}E[MAXN<<1];
int head[MAXN],ecnt;

void addedge(rg int x,rg int y,rg int w)
{
    E[++ecnt].to=y,E[ecnt].w=w;
    E[ecnt].nx=head[x],head[x]=ecnt;
}

int siz[MAXN];
int f[MAXN][MAXK];
ll c[MAXN];
ll ans;

il void dfs(rg int x,rg int fa)
{
    siz[x]=1;
    f[x][0]=1;
    for(rg int i=head[x];i;i=E[i].nx)
    {
        rg int y=E[i].to,w=E[i].w;
        if(y==fa)
            continue;
        dfs(y,x);
        siz[x]+=siz[y];
        ans += (ll) (n - siz[y]) * siz[y] * w;
        for(rg int p=0;p<k;++p)
            for(rg int q=0;q<k;++q)
                c[(p + q + w) % k] += f[x][p] * f[y][q];
        for(rg int j=0;j<k;++j)
            f[x][(j + w) % k] += f[y][j];
    }
}

int main()
{
  freopen("haskell.in","r",stdin);
  freopen("haskell.out","w",stdout);
    read(n);read(k);
    for(rg int i=1;i<n;++i)
    {
        rg int x,y,w;
        read(x);read(y);read(w);
        addedge(x,y,w);
        addedge(y,x,w);
    }
    dfs(1,0);
    for(rg int i=1;i<k;++i)
    {
        ans += (k-i) * c[i];
    }
    printf("%lld\n",ans/k);
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

原文地址:https://www.cnblogs.com/autoint/p/9807230.html

时间: 2024-08-07 18:02:39

test20181016 B君的第三题的相关文章

test20181018 B君的第三题

题意 B 君的第三题(shenyang) 题目描述 客似云来,万里无云 B 君得到了一个数组\(\{a_1,a_2,\dots,a_n\}\). B 君想通过修改让数组中个每对数都互质. 每次使一个数+1 或者-1 的代价是1. 不能将\(a_i\) 修改为0 或者负数. 问至少多少代价才可以让所有数两两互质. 输入格式 第一行一个整数n. 第二行n 个整数\(a_i\),表示数组初始值. 输出格式 一行一个数表示答案. 样例输入 5 2 4 6 8 10 样例输出 4 样例解释 修改为2, 3

2014马哥Linux0217中对0214三题的解答

前几天在做2014马哥Linux0214的作业的时候,发现其实这三题在0217中有解答,当然觉得马哥比自己写得好太多,所以忍不住要把马哥的答案贴出来,以供自己学习. 第一题:写一个脚本,用for循环实现显示/etc/init.d/functions./etc/rc.d/rc.sysinit./etc/fstab有多少行 #!/bin/bash for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab;do line

2016/1/12 第一题 输出 i 出现次数 第二题 用for循环和if条件句去除字符串中空格 第三题不用endwith 实现尾端字符查询

1 import java.util.Scanner; 2 3 4 public class Number { 5 6 private static Object i; 7 8 /* 9 *第一题 mingrikejijavabu中字符“i” 出现了几次,并将结果输出*/ 10 public static void main(String[] args) { 11 12 String r ="imingrikejijavabi"; 13 14 15 //第一种 截取 16 int a=

LeetCode 第三题,Longest Substring Without Repeating Characters

题目: Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest s

Java-集合-第三题 有如下Student 对象, private String name; private int age; private int score; private String classNum; 其中,classNum 表示学生的班号,例如“class05”。 有如下List List list = new ArrayList(); l

第三题 有如下Student 对象, private String name; private int age; private int score; private String classNum; 其中,classNum 表示学生的班号,例如“class05”. 有如下List List list = new ArrayList(); list.add(new Student(“Tom”, 18, 100, “class05”)); list.add(new Student(“Jerry”,

NOIP2005-普及组复赛-第三题-采药

题目描述 Description 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值.我会给你一段时间,在这段时间里,你可以采到一些草药.如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大.” 如果你是辰辰,你能完成这个任务吗? 输入输出格式 Input/output 输入格式:输

2014百度之星资格赛第三题

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 7837    Accepted Submission(s): 3350 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Z

第二题、第三题、第四题

1.以编程方式操作 HttpCachePolicy 类. HttpCachePolicy.SetExpires HttpCachePolicy.SetCacheability |NoCache|Private|Public|Server|ServerAndNoCache |ServerAndPrivate 2<%@ OutputCache Duration="60" VaryByParam="None" %>Duration 和 VaryByParam

第三题作业

第一题: import java.lang.Integer; import java.util.Arrays; class ArrDemo{     public static void main(String[] args){         int[] arr = new int[]{1,20,60,90,4};         //int[] arr = new int[5];//问题2.这个值并没有在错误判断里面,怎么判断?         System.out.println(Arra