题目:https://vijos.org/p/1892

分析:(100分其实用到各种c++优化,没什么实际意义,所以弄70就可以了)

题目很简单,很容易想出用树形DP,但是求方案数的时候,满满都是细节……,本渣考试时候就跪了……只能膜拜神犇代码……

 #include <cstdio>
#include <cstring>
//#include <algorithm> using namespace std; typedef long long LL; const int MaxN = ; struct Node{
int v;
Node *nxt;
}pool[MaxN << ],*tail=pool,*g[MaxN]; int n;
LL m;
LL h[MaxN][];
int fa[MaxN],f[MaxN][];
LL pre[MaxN],suf[MaxN]; inline void make_edge(int u,int v){
tail->v=v;tail->nxt=g[u];g[u]=tail++;
tail->v=u;tail->nxt=g[v];g[v]=tail++;
} inline int max(int a,int b){return a>b ? a : b;}
void dp(){
static int q[MaxN],l,r;
memset(fa,0xff,sizeof(fa));
for(fa[q[l=r=]=]=;l<=r;l++)
for(Node *p=g[q[l]];p;p=p->nxt) if(!~fa[p->v])
fa[q[++r]=p->v]=q[l];
for(int i=r;i>=;i--){
int u=q[i];
int maxt=0xc0c0c0c0;
int cnt=,j;
f[u][]=,f[u][]=;
h[u][]=,h[u][]=;
for(Node *p=g[u];p;p=p->nxt) if(p->v!=fa[u]){
LL dt=;
f[u][]+=max(f[p->v][],f[p->v][]);
f[u][]+=max(f[p->v][],f[p->v][]);
maxt=max(maxt,f[p->v][]+-max(f[p->v][],f[p->v][])); if(f[p->v][]>f[p->v][]) dt=h[p->v][];
else if(f[p->v][]<f[p->v][]) dt=h[p->v][];
else dt=(h[p->v][]+h[p->v][])%m;
pre[++cnt]=dt;suf[cnt]=dt;
(h[u][]*=dt)%=m;
}
pre[]=suf[cnt+]=;
for(int i=;i<=cnt;i++) (pre[i]*=pre[i-])%=m;
for(int i=cnt;i;i--) (suf[i]*=suf[i+])%=m;
f[u][]+=maxt;
j=;
for(Node *p=g[u];p;p=p->nxt) if(p->v!=fa[u]){
if(f[p->v][]+-max(f[p->v][],f[p->v][])==maxt)
(h[u][]+=pre[j-]*suf[j+]%m*h[p->v][]%m)%=m;
j++;
}
}
if(f[][]==f[][]) printf("%d\n%lld\n",f[][],(h[][]+h[][])%m);
else if(f[][]>f[][]) printf("%d\n%lld\n",f[][],h[][]);
else printf("%d\n%lld\n",f[][],h[][]);
}
int main()
{
scanf("%d",&n);
for(int i=;i<n;i++){
int u,v;scanf("%d%d",&u,&v);
make_edge(u,v);
}
scanf("%lld",&m);
dp();
return ;
}

细节反思:

1、求f和求g的过程可以一块写,思路比较清晰一点

2、求g[u][1]的时候的技巧:

  本渣只能想到先求所有的乘积,然后再枚举每一个位置的,除掉,因为取模只能求逆

  但此神犇的做法很厉害:

    先在求f的过程中把u的每个子节点的最优值记下来保存在数组中,并记下来u往叶子节点连边能得到的最大增值maxt

    然后把记最优值的数组从前往后累乘得到pre,从后往前乘得到suf

    然后对于每次枚举的连边的子节点i,首先判断连i所能得到的增值是否为maxt,如果是那么增加的方案数也就确定了:pre[i-1]*suf[i+1]*g[i][0]

细节方面真的很重要……

[vijos1892]树上的最大匹配(树形DP)的更多相关文章

  1. Vijos p1892 树上的最大匹配 树形DP+计数 被卡常我有特殊技巧heheda

    https://vijos.org/p/1892 此题需要手动开栈: <<; //256MB char *p=(char*)malloc(size)+size; __asm__(" ...

  2. BZOJ_4033_[HAOI2015]树上染色_树形DP

    BZOJ_4033_[HAOI2015]树上染色_树形DP Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的 ...

  3. 2021.07.17 P3177 树上染色(树形DP)

    2021.07.17 P3177 树上染色(树形DP) [P3177 HAOI2015]树上染色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.dp思想是需要什么,维护 ...

  4. 树上的等差数列 [树形dp]

    树上的等差数列 题目描述 给定一棵包含 \(N\) 个节点的无根树,节点编号 \(1\to N\) .其中每个节点都具有一个权值,第 \(i\) 个节点的权值是 \(A_i\) . 小 \(Hi\) ...

  5. 【BZOJ4033】[HAOI2015] 树上染色(树形DP)

    点此看题面 大致题意: 给你一棵点数为N的带权树,要你在这棵树中选择K个点染成黑色,并将其他的N-K个点染成白色.要求你求出黑点两两之间的距离加上白点两两之间距离的和的最大值. 树形\(DP\) 这道 ...

  6. 洛谷P3177 [HAOI2015]树上染色(树形dp)

    题目描述 有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之 ...

  7. BZOJ4033: [HAOI2015]树上染色(树形DP)

    4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3461  Solved: 1473[Submit][Stat ...

  8. bzoj 4033: [HAOI2015]树上染色【树形dp】

    准确的说应该叫树上分组背包?并不知道我写的这个叫啥 设计状态f[u][j]为在以点u为根的子树中有j个黑点,转移的时候另开一个数组,不能在原数组更新(因为会用到没更新时候的状态),方程式为g[j+k] ...

  9. BZOJ 4033[HAOI2015] 树上染色(树形DP)

    4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3188  Solved: 1366[Submit][Stat ...

随机推荐

  1. hbase shell 常用命令

    进入hbase shell console$HBASE_HOME/bin/hbase shell如果有kerberos认证,需要事先使用相应的keytab进行一下认证(使用kinit命令),认证成功之 ...

  2. pageX和pageY

    pageX() 属性是鼠标指针的位置,相对于文档的左边缘. pageY() 属性是鼠标指针的位置,相对于文档的上边缘. 例1 $(document).mousemove(function(e){ $( ...

  3. 虚拟机Linux----Ubuntu1204----安装jdk1.8

    1.介绍 这里主要讲一下,如何在Ubuntu1204下通过压缩包的方式安装jdk1.8,rpm的直接运行就行了. 2.步骤 2.1 下载 地址:http://www.oracle.com/techne ...

  4. 爆零后的感受外加一道强联通分量HDU 4635的题解

    今天又爆零了,又是又,怎么又是又,爆零爆多了,又也就经常挂嘴边了,看到这句话,你一定很想说一句””,弱菜被骂傻,也很正常啦. 如果你不开心,可以考虑往下看. 翻到E(HDU 4635 Strongly ...

  5. hdu String Problem(最小表示法入门题)

    hdu 3374 String Problem 最小表示法 view code#include <iostream> #include <cstdio> #include &l ...

  6. [转载] Android Metro风格的Launcher开发系列第一篇

    前言:从毕业到现在已经三年多了,回忆一下这三年基本上没有写过博客,总是觉得忙,没时间写,也觉得写博客没什么大用.但是看到很多大牛们都在写博客,分享自己的东西,所以嘛本着向大牛看齐,分享第一,记录第二的 ...

  7. Sample Join Analysis

    Sample data: student.txt 1,yaoshuya,25 2,yaoxiaohua,29 3,yaoyuanyie,15 4,yaoshupei,26 Sample data:sc ...

  8. 【温故而知新-Javascript】使用 Document 对象

    Document 对象时通往DOM功能的入口,它向你提供了当前文档的信息,以及一组可供探索.导航.搜索或操作结构与内容的功能. 我们通过全局变量document访问Document对象,它是浏览器为我 ...

  9. 【每天一题ACM】 斐波那契数列(Fibonacci sequence)的实现

    最近因为一些原因需要接触一些ACM的东西,想想写个blog当作笔记吧!同时也给有需要的人一些参考 话不多说,关于斐波那契数列(Fibonacci sequence)不了解的同学可以看看百度百科之类的, ...

  10. [转载]ExtJs4 笔记(3) Ext.Ajax 对ajax的支持

    作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)     本篇主要介绍一下ExtJs常用的几个对JS语法的扩展支持,包括Ajax封装,函数事 ...