LINK:Decompose





看起来很难 实际上也很难 考验选手的dp 树链剖分 矩阵乘法的能力。

容易列出dp方程 暴力dp 期望得分28.

对于链的情况 容易发现dp方程可以转矩阵乘法 然后利用线段树维护矩阵即可。

这个矩阵很容易列出这里不再赘述。

对于100分 容易想到动态dp模型 LCT写动态dp是万万不能的。

而且这道题的dp方程和其他儿子也有些关系。

考虑树链剖分 然后分别计算轻儿子和重儿子的贡献。

让重儿子利用矩阵来进行转移 轻儿子当做常数.

这样每次修改的时候 修改的节点最多只有logn个.

用set维护需要维护的东西即可。

剩下的就是树链剖分型动态dp的套路 每次利用链顶的矩阵信息更新下一个节点即可。

一个细节:叶子节点可以直接列成\(L\cdot L\)的矩阵 只有第一个元素有值 这样更容易实现。

一个细节:可能矩阵乘法出来的值和原来的值不尽相同 此时考虑更新set的时候利用原来信息更新 然后更新原来信息即可。

思维难度:高 代码难度:极高。

const ll MAXN=100010;
ll n,Q,L,len,id;
ll top[MAXN],pos[MAXN],dfn[MAXN],fa[MAXN],c[MAXN],sum[MAXN];
ll a[MAXN][5],d[MAXN],son[MAXN],sz[MAXN],f[MAXN][5],w[MAXN];
ll lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];
multiset<ll>s[MAXN][4];
struct wy
{
ll b[5][5];
ll l,r;
wy(){l=r=0;rep(1,L,i)rep(1,L,j)b[i][j]=-INF;}
wy friend operator +(wy a,wy b)
{
wy c;c.l=b.l;c.r=a.r;
rep(1,L,i)rep(1,L,j)rep(1,L,k)
c.b[i][j]=max(c.b[i][j],a.b[i][k]+b.b[k][j]);
return c;
}
}t[MAXN<<2];
inline void add(ll x,ll y)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
}
inline void dfs(ll x,ll father)
{
d[x]=d[father]+1;fa[x]=father;sz[x]=1;
rep(2,L,j)f[x][j]=-INF;w[x]=-INF;
f[x][1]=a[x][1];ll ans=0;
go(x)if(tn!=father)
{
dfs(tn,x);
if(sz[tn]>sz[son[x]])son[x]=tn;
sz[x]+=sz[tn];
rep(2,L,j)f[x][j]=max(f[x][j]+w[tn],f[tn][j-1]+a[x][j]+ans);
ans+=w[tn];
}
f[x][1]+=ans;
rep(1,L,j)w[x]=max(w[x],f[x][j]);
go(x)if(tn!=father&&tn!=son[x])
rep(1,L-1,j)s[x][j].insert(f[tn][j]-w[tn]);
sum[x]=ans-w[son[x]];
}
inline void dp(ll x,ll father)
{
top[x]=father;dfn[x]=++id;pos[id]=x;c[father]=x;
if(!son[x])return;
dp(son[x],father);
go(x)if(tn!=son[x]&&tn!=fa[x])dp(tn,tn);
}
inline void build(ll p,ll l,ll r)
{
l(p)=l;r(p)=r;
if(l==r)
{
ll x=pos[l];
if(sz[x]==1)
{
rep(1,L,i)rep(1,L,j)t[p].b[i][j]=-INF;
t[p].b[1][1]=a[x][1];
}
else
{
rep(1,L,i)t[p].b[i][1]=a[x][1]+sum[x];
ll flag=s[x][1].size();
rep(2,L,j)
{
ll ww=flag?(*--s[x][j-1].end()):-INF;
rep(1,L,i)t[p].b[i][j]=a[x][j]+sum[x]+ww;
t[p].b[j-1][j]-=ww;
}
}
return;
}
ll mid=(l+r)>>1;
build(zz,l,mid);
build(yy,mid+1,r);
t[p]=t[yy]+t[zz];
}
inline void change(ll p,ll x)
{
if(l(p)==r(p))
{
ll x=pos[l(p)];
if(sz[x]==1)
{
rep(1,L,i)rep(1,L,j)t[p].b[i][j]=-INF;
t[p].b[1][1]=a[x][1];
}
else
{
rep(1,L,i)t[p].b[i][1]=a[x][1]+sum[x];
ll flag=s[x][1].size();
rep(2,L,j)
{
//cout<<s[x][j-1].size()<<endl;
ll ww=flag?(*(--s[x][j-1].end())):-INF;
rep(1,L,i)t[p].b[i][j]=a[x][j]+sum[x]+ww;
t[p].b[j-1][j]-=ww;
//cout<<t[p].b[j-1][j]<<endl;
}
//rep(1,L,i){rep(1,L,j)cout<<t[p].b[i][j]<<' ';cout<<endl;}
}
return;
}
ll mid=(l(p)+r(p))>>1;
if(x<=mid)change(zz,x);
else change(yy,x);
t[p]=t[yy]+t[zz];
}
inline wy ask(ll p,ll l,ll r)
{
if(l<=l(p)&&r>=r(p))return t[p];
ll mid=(l(p)+r(p))>>1;
if(l>mid)return ask(yy,l,r);
if(r<=mid)return ask(zz,l,r);
return ask(yy,l,r)+ask(zz,l,r);
}
inline void Tchange(ll x)
{
ll fx=top[x];
while(fx!=1)
{
change(1,dfn[x]);
wy w1=ask(1,dfn[fx],dfn[c[fx]]);
x=fa[fx];//修改x.
ll cnt1=-INF;
rep(1,L,i)cnt1=max(cnt1,w1.b[1][i]);
sum[x]=sum[x]-w[fx]+cnt1;
fep(L-1,1,i)
{
s[x][i].erase(s[x][i].find(f[fx][i]-w[fx]));
s[x][i].insert(w1.b[1][i]-cnt1);
f[fx][i]=w1.b[1][i];
}
w[fx]=cnt1;fx=top[x];
}
change(1,dfn[x]);
wy ww=ask(1,dfn[1],dfn[c[1]]);ll ans=-INF;
rep(1,L,i)
{
ans=max(ans,ww.b[1][i]);
//cout<<ww.b[1][i]<<' ';
}
//puts("");
putl(ans);
}
signed main()
{
freopen("decompose.in","r",stdin);
freopen("decompose.out","w",stdout);
get(n);get(Q);get(L);
rep(2,n,i)add(read(),i);
rep(1,n,i)rep(1,L,j)get(a[i][j]);
dfs(1,0);dp(1,1);
build(1,1,n);
//wy ww=ask(1,dfn[1],dfn[c[1]]);ll ans=-INF;
//rep(1,L,i)ans=max(ans,ww.b[1][i]),cout<<ww.b[1][i]<<' ';
//puts("");putl(ans);
rep(1,Q,i)
{
ll get(x);
rep(1,L,j)get(a[x][j]);
Tchange(x);
}
return 0;
}

6.3 省选模拟赛 Decompose 动态dp 树链剖分 set的更多相关文章

  1. 4.12 省选模拟赛 LCA on tree 树链剖分 树状数组 分析答案变化量

    LINK:duoxiao OJ LCA on Tree 题目: 一道树链剖分+树状数组的神题. (直接nQ的暴力有50. 其实对于树随机的时候不难想到一个算法 对于x的修改 暴力修改到根. 对于儿子的 ...

  2. 5210: 最大连通子块和 动态DP 树链剖分

    国际惯例的题面:这题......最大连通子块和显然可以DP,加上修改显然就是动态DP了......考虑正常情况下怎么DP:我们令a[i]表示选择i及i的子树中的一些点,最大连通子块和;b[i]表示在i ...

  3. BZOJ4712洪水——动态DP+树链剖分+线段树

    题目描述 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到 山顶放了格水.于是小A面前出现了一个瀑布.作为平民的小A只好老实巴交地爬山堵水.那么 ...

  4. 3.28 省选模拟赛 染色 LCT+线段树

    发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...

  5. 5.10 省选模拟赛 拍卖 博弈 dp

    LINK:拍卖 比赛的时候 前面时间浪费的有点多 写这道题的时候 没剩多少时间了. 随便设了一个状态 就开始做了. 果然需要认真的思考.其实 从我的状态的状态转移中可以看出所有的结论. 这里 就不再赘 ...

  6. 5.12 省选模拟赛 T2 贪心 dp 搜索 差分

    LINK:T2 这题感觉很套路 但是不会写. 区间操作 显然直接使用dp不太行 直接爆搜也不太行复杂度太高. 容易想到差分 由于使得整个序列都为0 那么第一个数也要i差分前一个数 强行加一个0 然后 ...

  7. 5.10 省选模拟赛 tree 树形dp 逆元

    LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...

  8. 4.11 省选模拟赛 序列 二分 线段树优化dp set优化dp 缩点

    容易想到二分. 看到第一个条件容易想到缩点. 第二个条件自然是分段 然后让总和最小 容易想到dp. 缩点为先:我是采用了取了一个前缀最小值数组 二分+并查集缩点 当然也是可以直接采用 其他的奇奇怪怪的 ...

  9. 4.3 省选模拟赛 序列游戏 dp

    可以发现 某一段被删除后状态难以表示 也难以链接起来. 考虑暴力 有40分的状压dp 暴力存状态 然后枚举转移即可.最后注意和f[0]这个状态取max 不然一分都没有. const int MAXN= ...

随机推荐

  1. 洛谷 P4910 帕秋莉的手环

    题意 多组数据,给出一个环,要求不能有连续的\(1\),求出满足条件的方案数 \(1\le T \le 10, 1\le n \le 10^{18}\) 思路 20pts 暴力枚举(不会写 60pts ...

  2. Electricity POJ - 2117 + SPF POJ - 1523 去除割点后求强连通分量个数问题

    Electricity POJ - 2117 题目描述 Blackouts and Dark Nights (also known as ACM++) is a company that provid ...

  3. NameNode是如何存储元数据的?

    1.NN的作用 保存HDFS上所有文件的元数据! 接受客户端的请求! 接受DN上报的信息,给DN分配任务(维护副本数)! 2.元数据的存储 元数据存储在fsiamge文件+edits文件中! fsim ...

  4. Rsync服务常见问题及解决

    1. rsync服务端开启的iptables防火墙/selinux没关 [客户端的错误] No route to host [错误演示过程] [root@nfs01 tmp]# rsync -avz ...

  5. 使用wsl2時碰到的問題

    1.啓動wsl系统时出现“参考的对象类型不支持尝试的操作”. 解决方法: netsh winsock reset

  6. java 基本语法(十一) 数组(四)数组的常见算法

    1.数组的创建与元素赋值: 杨辉三角(二维数组).回形数(二维数组).6个数,1-30之间随机生成且不重复. 杨辉三角 public class YHSJ { public static void m ...

  7. python 装饰器(三):装饰器实例(一)

    示例 7-15 定义了一个装饰器,它会在每次调用被装饰的函数时计时,然后把经过的时间.传入的参数和调用的结果打印出来.示例 7-15 一个简单的装饰器,输出函数的运行时间 import time de ...

  8. 数据可视化实例(十四):带标记的发散型棒棒糖图 (matplotlib,pandas)

    偏差 (Deviation) 带标记的发散型棒棒糖图 (Diverging Lollipop Chart with Markers) 带标记的棒棒糖图通过强调您想要引起注意的任何重要数据点并在图表中适 ...

  9. Python之爬虫(二十四) 爬虫与反爬虫大战

    爬虫与发爬虫的厮杀,一方为了拿到数据,一方为了防止爬虫拿到数据,谁是最后的赢家? 重新理解爬虫中的一些概念 爬虫:自动获取网站数据的程序反爬虫:使用技术手段防止爬虫程序爬取数据误伤:反爬虫技术将普通用 ...

  10. three.js 制作属于自己的动态二维码

    今天郭先生说一下用canvas解析图片流,然后制作一个动态二维码的小案例,话不多说先上图,在线案例点击博客原文.这是郭先生的微信二维码哦! 1. 解析图片流 canvas = document.cre ...