bzoj 5072 [Lydsy1710月赛]小A的树——树形dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5072
发现对于每个子树,黑点个数确定时,连通块的大小取值范围一定是一段区间;所以考虑只最小化最小值、最大化最大值,记 f 和 g 简单dp即可。
注意可能从当前子树里选0个点!此时会用自己更新自己!!所以要先复制一份原来的用来更新!
快速回答询问,本可以记差分数组,每个子树算完后给合法部分区间赋值;但空间开不下。
于是绞尽脑汁,终于想出可以开 bool 数组分块来赋值!!然而WA得不行。
交流后发现那个“取值是一段区间”的性质,在全局也是适用的(很明显……)!所以只要更新一下合法的最值就行了……
然后对拍半天 bool 分块,发现因为有 0 的值,所以标号应该是 0~base-1 这样;而且代码里注释的那个部分是 < 和 >= 而不是 <= 和 >!
然后又因为数据生成出错而以为自己还是不对而又拍、查了半天;最后分块的方法虽然慢一点,但也A了。感觉很好!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=,M=;
int T,n,q,base,hd[N],xnt,to[N<<],nxt[N<<],siz[N],f[N][N],g[N][N],tf[N],tg[N];
bool b[N],ok[N][N],ok2[M][N];//siz,black
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='') ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return fx?ret:-ret;
}
void add(int x,int y)
{
to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;
to[++xnt]=x;nxt[xnt]=hd[y];hd[y]=xnt;
}
int calc(int x){return x/base+;}//0~base-1
void dfs(int cr,int fa)
{
f[cr][b[cr]]=g[cr][b[cr]]=; siz[cr]=b[cr];
for(int i=hd[cr],v;i;i=nxt[i])
if((v=to[i])!=fa)
{
dfs(v,cr);
memcpy(tf,f[cr],sizeof f[cr]);
memcpy(tg,g[cr],sizeof g[cr]);
for(int j=siz[cr]+siz[v];j>=b[cr];j--)
for(int k=max((int)b[v],j-siz[cr]);k<=siz[v]&&k<=j;k++)
{
f[cr][j]=min(f[cr][j],tf[j-k]+f[v][k]);
g[cr][j]=max(g[cr][j],tg[j-k]+g[v][k]);
}
siz[cr]+=siz[v];
}
/*
for(int i=0;i<=siz[cr];i++)
f[0][i]=min(f[0][i],f[cr][i]),
g[0][i]=max(g[0][i],g[cr][i]);
*/
for(int i=;i<=siz[cr];i++)
{
if(f[cr][i]>g[cr][i])continue;
int l=calc(f[cr][i]),r=calc(g[cr][i]);
if(r-l<=)
{
for(int j=f[cr][i];j<=g[cr][i];j++)
ok[j][i]=;
}
else
{
for(int j=l+;j<r;j++)ok2[j][i]=;
int lm=l*base;
for(int j=f[cr][i];j<lm;j++)ok[j][i]=;//<
lm=(r-)*base;
for(int j=g[cr][i];j>=lm;j--)ok[j][i]=;//>=
}
}
}
int main()
{
T=rdn();
while(T--)
{
n=rdn(); q=rdn(); base=sqrt(n);
memset(hd,,sizeof hd); xnt=;
memset(ok,,sizeof ok); memset(ok2,,sizeof ok2);
for(int i=,u,v;i<n;i++)
{
u=rdn(); v=rdn(); add(u,v);
}
for(int i=;i<=n;i++)b[i]=rdn();
memset(f,0x3f,sizeof f); memset(g,-,sizeof g);
dfs(,);
for(int i=,x,y,d;i<=q;i++)
{
x=rdn(); y=rdn(); d=calc(x);
puts((ok[x][y]||ok2[d][y])?"YES":"NO");
//puts(x>=f[0][y]&&x<=g[0][y]?"YES":"NO");
}
puts("");
}
return ;
}
bzoj 5072 [Lydsy1710月赛]小A的树——树形dp的更多相关文章
- [BZOJ 5072][Lydsy1710月赛]小A的树
传送门 \(\color{green}{solution}\) 嗯...其实我也不太会,所以大胆猜个结论吧(后来证了一下,然后放弃了...). 我们发现如果要使一个联通块的黑点数量为\(k\)的方案最 ...
- BZOJ5072:[Lydsy1710月赛]小A的树(树形DP)
Description BZOJ只是扔了个下载链接 Solution 设$f[x][i]$表示$x$点选中$i$个黑点的最小连通块. 设$g[x][i]$表示$x$点选中$i$个黑点的最大连通块. 转 ...
- 【BZOJ5072】[Lydsy十月月赛]小A的树 树形DP
[BZOJ5072][Lydsy十月月赛]小A的树 题解:考虑我们从一个联通块中替换掉一个点,导致黑点数量的变化最多为1.所以我们考虑维护对于所有的x,y的最大值和最小值是多少.如果询问的y在最大值和 ...
- bzoj 5072 小A的树 —— 树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5072 由于对于一个子树,固定有 j 个黑点,连通块大小是一个连续的范围: 所以记 f[i][ ...
- 牛客挑战赛30 小G砍树 树形dp
小G砍树 dfs两次, dp出每个点作为最后一个点的方案数. #include<bits/stdc++.h> #define LL long long #define fi first # ...
- [BZOJ 5074][Lydsy1710月赛]小B的数字
传送门 \(\color{green}{solution}\) 设 \[b_{i}=2^{w_{i}},sum= \sum_{i=1}^{n}{w_{i}}\] 则对于任意\(a_{i}\)都有 \[ ...
- 【bzoj5072】[Lydsy十月月赛]小A的树 树形背包dp
题解: 比较好想 首先注意到如果最暴力的做法复杂度无法接受 而5000的范围基本是n^2做法了 只使用已经遍历过的点数目和当前子树中的点数目转移我们知道复杂度是n^2的 于是大胆猜测一波同一个节点为根 ...
- 小A的树 - 树形DP
题面 1 9 4 4 1 1 5 1 2 3 2 3 6 6 7 6 8 9 6 0 1 0 1 0 0 1 0 1 3 2 7 3 4 0 9 5 YES YES NO NO 题解 n <= ...
- 5073 [Lydsy1710月赛]小A的咒语
LINK:[Lydsy1710月赛]小A的咒语 每次给定两个串 要求从a串中选出x段拼成B串 能否做到.T组数据. \(n\leq 100000,m\leq 100000,T\leq 10,x\leq ...
随机推荐
- Go语言中的单引号、双引号、反引号
=Start= 搜索关键字: golang single quotes golang double quotes golang back quotes 参考结果: 结论写在最前:在Go语言中不倾向于使 ...
- sonar + ieda实现提交代码前代码校验
代码风格不同一直是一件停头疼的事情,因为不同的工作经验,工作经历,每个人的代码风格不尽相同,造成一些代码在后期的维护当中难以维护, 查阅一些资料之后发现 idea + sonar 的方式比较适合我,实 ...
- MySQL获得指定数据表中auto_increment自增id值的方法及实例
http://kb.cnblogs.com/a/2357592/很多情况下,我们要提前用到当前某个表的auto_increment自增列id,可以通过执行sql语句来查询到这个id值. show ta ...
- HDU 1418 抱歉 (欧拉公式)
[题目链接]:pid=1418">click here~~ [题目大意]: 假设平面上有n个点,而且每一个点至少有2条曲线段和它相连,就是说,每条曲线都是封闭的.同一时候,我们规定: ...
- VMware安装ubuntu学习笔记(只是笔记)
VMware安装ubuntu开机黑屏/死机 1- Edit Ubuntu VM Configuration file (.vmx) 2- Add the following line cpuid.1. ...
- hdu1878欧拉回路(DFS+欧拉回路)
欧拉回路 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- gcc參数总结
/*gcc 命令总结*/ 补充下gcc的知识,免得被大自然说编译原理不行.. 1.-o 參数 參数说明: -o參数用来指定生成程序的名字 gcc test.c 会编译出一个名为a.out的程序 gcc ...
- 在Mac OS中配置CMake的详细图文教程http://blog.csdn.net/baimafujinji/article/details/78588488
CMake是一个比make更高级的跨平台的安装.编译.配置工具,可以用简单的语句来描述所有平台的安装(编译过程).并根据不同平台.不同的编译器,生成相应的Makefile或者project文件.本文主 ...
- Spring中的面向切面编程(AOP)简介
一.什么是AOP AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面 ...
- java 浮点数
package precisenumber; //import java.util.*;public class PreciseNumber { public int fore; public int ...