传送门.

题解:


最主要的问题是如何判断一个数是否合法,这就需要发现性质了。

这个状态划分还是不太容易想到,

每次加的数\(∈[0,k)\),也就是个位一直在变变变,更高的位每次都是加一,这启发我们状态的划分。

这个时候可以利用数位dp的逐位确定思想,在尝试后,发现可以从高位到低位,因为当高位确定后,高位就不会变了,那么高位的最大值也就确定了。

设\(f[i][p][a]\),\(i\)含义如上,\(i+1\)位后的最大值是p,\(2-i\)位是0,当前个位是\(a\),使第\(i\)位加1后个位变成什么?

\(i=2\)时直接暴力处理,\(f[i]\)可以\(O(k)\)由\(f[i-1]\)推出来,复杂度\(O(n*k^3)\)。

有了f方便处理出\(g[i][p][x][a]\),\(i、p、a\)含义如上,x表示第i位要+x,

这里\(x=0\),g的值就是a,然后g自己推自己,复杂度\(O(n*k^3)\)。

接下来的部分就很傻逼了,带根联通块,直接在dfs序上dp,做到个位的时候,再跳跳看能不能跳到那个位去就好了。

Code:


#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std; const int N = 505; int n, k;
int d[N], x, y;
vector<int> e[N];
#define pb push_back
#define si size() int p[N], q[N], np[N], p0, fa[N]; void dg(int x) {
p[x] = ++ p0; np[p0] = x;
ff(j, 0, e[x].si) {
int y = e[x][j];
if(fa[x] != y) fa[y] = x, dg(y);
}
q[x] = p0;
} const int mo = 1e9 + 7; int f[N][10][10], g[N][10][10][10];
ll h[N][N][10][10]; void add(ll &x, ll y) {
(x += y) >= mo ? x -= mo : 0;
} int T; int main() {
// freopen("buried.in", "r", stdin);
// freopen("buried.out", "w", stdout);
k = 10;
for(scanf("%d", &T); T; T --) {
fo(i, 1, n) e[i].clear();
memset(h, 0, sizeof h);
fo(i, 1, n) fa[i] = 0; p0 = 0;
scanf("%d", &n);
fo(i, 1, n - 1) {
scanf("%d %d", &x, &y);
e[x].pb(y); e[y].pb(x);
}
fo(i, 1, n) scanf("%d", &d[i]);
fo(i, 1, n) sort(e[i].begin(), e[i].end());
dg(1);
//Initialization of F
ff(p, 0, k) {
ff(a, 0, k) if(p || a) {
int x = a;
while(x < k) {
x += max(x, p);
}
f[1][p][a] = x % k;
}
}
//dp F
fo(i, 2, n - 1) {
ff(p, 0, k) {
ff(a, 0, k) {
int x = a;
fo(c, 1, k) x = f[i - 1][max(p, c - 1)][x];
f[i][p][a] = x;
}
}
}
//dp g
fo(i, 2, n) {
ff(p, 0, k) {
ff(a, 0, k) {
g[i][p][0][a] = a;
ff(x, 1, k) g[i][p][x][a] = f[i - 1][max(x - 1, p)][g[i][p][x - 1][a]];
}
}
}
//dp h
ll ans = 0;
fo(j, 1, n) h[1][j][0][1] = 1;
fo(i, 1, n) {
int num = d[np[i]];
int ni = q[np[i]] + 1;
fo(j, 2, n) {
ff(p, 0, k) ff(a, 0, k) if(h[i][j][p][a] && (p || a)) {
add(h[i + 1][j - 1][max(p, num)][g[j][p][num][a]], h[i][j][p][a]);
add(h[ni][j][p][a], h[i][j][p][a]);
}
}
ff(p, 0, k) ff(a, 0, k) if(h[i][1][p][a] && (p || a)) {
int x = a;
while(x < num) x += max(x, p);
if(x == num) add(ans, h[i][1][p][a]);
add(h[ni][1][p][a], h[i][1][p][a]);
}
}
pp("%lld\n", ans);
}
}

CodeChef Max-digit Tree(动态规划)的更多相关文章

  1. 【Codeforces715C&716E】Digit Tree 数学 + 点分治

    C. Digit Tree time limit per test:3 seconds memory limit per test:256 megabytes input:standard input ...

  2. Codeforces 716 E Digit Tree

    E. Digit Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard input ...

  3. 【题解】Digit Tree

    [题解]Digit Tree CodeForces - 716E 呵呵以为是数据结构题然后是淀粉质还行... 题目就是给你一颗有边权的树,问你有多少路径,把路径上的数字顺次写出来,是\(m\)的倍数. ...

  4. Codechef Union on Tree

    Codechef Union on Tree https://www.codechef.com/problems/BTREE 简要题意: 给你一棵树,\(Q\)次询问,每次给出一个点集和每个点的\(r ...

  5. 【Codeforces 715C】Digit Tree(点分治)

    Description 程序员 ZS 有一棵树,它可以表示为 \(n\) 个顶点的无向连通图,顶点编号从 \(0\) 到 \(n-1\),它们之间有 \(n-1\) 条边.每条边上都有一个非零的数字. ...

  6. Codechef Observing the Tree

    Home » Practice(Hard) » Observing the Tree   https://www.codechef.com/problems/QUERY Observing the T ...

  7. HDU 1003 Max Sum【动态规划求最大子序列和详解 】

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  8. CF715C:Digit Tree

    传送门 一句话怎么说来着 算法+高级数据结构=OI 现在我感觉到的是 我会的算法+我会的高级数据结构=WA 这道题提交了三四十次,从刚看题到完全写好花了好几天..,主要死于看错费马小定理的适用条件. ...

  9. CF 716E. Digit Tree [点分治]

    题意:一棵树,边上有一个个位数字,走一条路径会得到一个数字,求有多少路径得到的数字可以整除\(P\) 路径统计一般就是点分治了 \[ a*10^{deep} + b \ \equiv \pmod P\ ...

  10. hdu 1003 Max Sum (动态规划)

    转载于acm之家http://www.acmerblog.com/hdu-1003-Max-Sum-1258.html Max Sum Time Limit: 2000/1000 MS (Java/O ...

随机推荐

  1. 红帽虚拟化RHEV-PXE批量安装RHEV-H

    目录 目录 前言 软件环境 前提 部署 PXE 环境 使用 yum 安装所需软件 配置 DHCP 配置 TFTP-Server 配置 vsftpd 服务用于提供安装系统所需软件包 安装 kicksta ...

  2. 初窥AST

    一个简单的AST示例: AST结构: 里面有program.name.loc.type.comments.tokens 先看program: 重点关注program里面的body这个数组: JS引擎中 ...

  3. 《图解设计模式》读书笔记7-2 Mediator模式

    目录 Mediator模式简介 示例程序 示例程序类图 代码 Mediator模式角色和类图 角色 模式类图 思路拓展 简单化 角色复用 Mediator模式简介 Mediator模式即中介者模式,可 ...

  4. 机器学习--如何将NLP应用到深度学习(3)

    数据收集以后,我们下面接着要干的事情是如何将文本转换为神经网络能够识别的东西.   词向量 作为自然语言,只有被数学化才能够被计算机认识和计算.数学化的方法有很多,最简单的方法是为每个词分配一个编号, ...

  5. Eureka-server配置servlet.context-path后导致Eureka-client注册到server问题

    在springboot项目里配置了servlet.context-path(应用上下文路径),也称之为项目路径,该配置让项目URL后增加配置的值.如果在Eureka-server中配置该值,当然也会改 ...

  6. PHP foreach &$ 引发的bug

    在使用foreach &$来更新数据的时候,造成数据被更新掉了 $arr = array(1,2,3,4,5); foreach ($arr as &$row) { $row += 1 ...

  7. jsp自定义标签处理转义字符

    sun公司提供的jstl虽然比较强大,但是开发中很难满足我们所有的需求,并且开发也禁止在jsp中写很多java代码,因此很多场景需要自己定义标签进行项目开发 sun提供的标签库引用方式:<%@t ...

  8. Spring Boot & ES 实战,值得参考!

    作者:废物大师兄 cnblogs.com/cjsblog/p/9756978.html 1. 前言 1.1. 集成方式 Spring Boot中集成Elasticsearch有4种方式: REST C ...

  9. 【洛谷p3956】棋盘

    日常blog(✧◡✧) 棋盘[题目链接] 算法: 然后这是2017普及组: first.关于颜色处理:让c[i][j]=color+1:这样无色=0,红色=1,黄色=2: 然后其实是记忆化,将记答案的 ...

  10. 中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结

    中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结 标签:数学方法--数论 阅读体验:https://zybuluo.com/Junlier/note/1300035 前置浅讲 前 ...