博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【洛谷4719】 动态dp(树链剖分,dp,矩阵乘法)
阅读量:5818 次
发布时间:2019-06-18

本文共 2704 字,大约阅读时间需要 9 分钟。

前言

其实我只是为了过掉模板而写的ddp,实际应用被吊着锤

Solution

并不想写详细的过程

一句话过程:将子树中轻儿子的贡献挂到这个点上面来

详细版:(引用yyb)

总结一下的话,大致的过程是这样子的:首先我们考虑我们的转移方程,发现能够将其改写为矩乘的形式,那么我们首先将转移改为矩乘。我们把轻链和重链的转移分开考虑。这样子想,我们的重链被我们单独拎了出来,每个重链上都挂上了若干轻儿子,显然轻儿子对于重链上的独立集的选择是没有影响的,换而言之,如果轻儿子的贡献考虑完之后,那么等价于链上每个点选或者不选有一个权值,求最大独立集。而对于链上的这个东西,是可以直接用线段数维护矩阵支持修改和查询的,那么这题就只需要这么做就好了。即只修改这个点到达根节点上的所有轻链对于父亲的贡献,对于重儿子的贡献先暂时不考虑,每次线段树查询矩阵乘积即可求解出每个点的矩阵,就可以快速求解答案了

代码实现

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define re register#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)inline int gi(){ int f=1,sum=0;char ch=getchar(); while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();} return f*sum;}const int N=100010;const ll Inf=1e18+10;int a[N],front[N],nxt[N<<1],to[N<<1],cnt,n,m,dep[N],son[N],siz[N],fa[N],top[N],dfn[N],Time,id[N],bot[N];void Add(int u,int v){ to[++cnt]=v;nxt[cnt]=front[u];front[u]=cnt;}struct matrix{ ll a[2][2]; ll*operator [](int x){return a[x];}; matrix operator*(matrix b)const{ matrix c; for(int i=0;i<2;i++) for(int j=0;j<2;j++){ c[i][j]=0; for(int k=0;k<2;k++) c[i][j]=max(c[i][j],a[i][k]+b[k][j]); } return c; }}t[N<<2],tmp[N];void dfs1(int u,int f){ dep[u]=dep[f]+1;siz[u]=1;fa[u]=f; for(int i=front[u];i;i=nxt[i]){ int v=to[i]; if(v==f)continue; dfs1(v,u); siz[u]+=siz[v];if(siz[v]>siz[son[u]])son[u]=v; }}void dfs2(int u,int tp){ top[u]=tp;dfn[u]=++Time;id[Time]=u; if(son[u]){dfs2(son[u],tp),bot[u]=bot[son[u]];} else bot[u]=u; for(int i=front[u];i;i=nxt[i]){ int v=to[i]; if(v==fa[u] || v==son[u])continue; dfs2(v,v); }}ll f[N][2];void dp(int u){ f[u][1]=a[u]; for(int i=front[u];i;i=nxt[i]){ int v=to[i]; if(v==fa[u])continue; dp(v); f[u][0]+=max(f[v][1],f[v][0]); f[u][1]+=f[v][0]; }}void build(int o,int l,int r){ if(l==r){ int u=id[l];int g0=0,g1=a[u]; for(int i=front[u];i;i=nxt[i]){ int v=to[i]; if(v==fa[u] || v==son[u])continue; g0+=max(f[v][1],f[v][0]);g1+=f[v][0]; } tmp[l]=t[o]=(matrix){g0,g0,g1,-Inf}; return; } int mid=(l+r)>>1; build(o<<1,l,mid);build(o<<1|1,mid+1,r); t[o]=t[o<<1]*t[o<<1|1];}//------------以上是dp+树剖-----------------------------------------------void Modify(int o,int l,int r,int p){ if(l==r){t[o]=tmp[l];return;} int mid=(l+r)>>1; if(p<=mid)Modify(o<<1,l,mid,p); else Modify(o<<1|1,mid+1,r,p); t[o]=t[o<<1]*t[o<<1|1];}matrix query(int o,int l,int r,int posl,int posr){ if(posl==l && posr==r)return t[o]; int mid=(l+r)>>1; if(mid>=posr)return query(o<<1,l,mid,posl,posr); else if(mid

转载于:https://www.cnblogs.com/mle-world/p/10263735.html

你可能感兴趣的文章
SHELL十三问[转载自CU论坛]
查看>>
Linux文件传输scp和rsync断点续传
查看>>
现代软件工程—构建之法---第五章:练习与讨论
查看>>
UNIX环境高级编程——死锁
查看>>
linux时钟浅析
查看>>
软件测试发展方向
查看>>
initrd image比lvm.conf文件舊導致RHCS切換服務unmount failed,reboot
查看>>
数据结构 Job
查看>>
leetcode之Spiral Matrix
查看>>
【国家集训队】middle
查看>>
webpack window 添加ES6支出
查看>>
比较css中单位px,em和rem的区别
查看>>
2014/03/04
查看>>
用定时器实现逐渐放大层的功能
查看>>
正则表达式 非获取匹配
查看>>
jdk版本及编译版本导致服务器部署UnsupportedClassVersionError错误
查看>>
Android升级ADT22后会报ClassNotFoundException的原因分析
查看>>
live555的编译及使用
查看>>
Longest Palindromic Substring
查看>>
springmvc注解事例
查看>>