文章目录

  • 题目描述
  • 解析
  • 代码

题目描述

所谓线段树维护dp,就是在线段树上维护dp

(逃)

解析

把树剖一下后就变成了区间问题
考虑建一棵线段树,每一个结点都是一个背包
这样就能区间查询,也能带修了
这种做法复杂度其实并不理想,是logn*dp合并复杂度
本题背包就是m2lognm^2lognm2logn
但是如果出题人想考这个肯定会在数据范围上放你一条生路啦
(调了半天结果树剖挂了就离谱)

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e4+100;
const int M=2e6+100;
const ll mod=1ll<<31;
ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();};while(isdigit(c)){x=x*10+c-'0';c=getchar();};return x*f;
}
int n,m,A,B,Q;
struct edge{int to,nxt;
}p[N<<1];
int fi[N],cnt=-1;
void addline(int x,int y){p[++cnt]=(edge){y,fi[x]};fi[x]=cnt;
}
int fa[N],dfn[N],pos[N],low[N],top[N],tim,siz[N],hson[N];
void dfs1(int x,int f){fa[x]=f;siz[x]=1;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==f) continue;dfs1(to,x);siz[x]+=siz[to];if(!hson[x]||siz[hson[x]]<siz[to]) hson[x]=to;}return;
}
void dfs2(int x,int tp){top[x]=tp;dfn[++tim]=x;pos[x]=tim;if(hson[x]) dfs2(hson[x],tp);for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==fa[x]||to==hson[x]) continue;dfs2(to,to);}
}
#define mid ((l+r)>>1)
#define ls (k<<1)
#define rs (k<<1|1)
int T[N][55];
struct bag{ll dp[55];ll mx[55];
}tr[N<<2];
void merge(bag a,bag b,bag &ans){memset(ans.dp,-0x3f,sizeof(ans.dp));memset(ans.mx,-0x3f,sizeof(ans.mx));ans.dp[0]=ans.mx[0]=0;for(int k=1;k<=m;k++){for(int i=0;i<=k;i++) ans.dp[k]=max(ans.dp[k],a.dp[i]+b.dp[k-i]);}for(int k=1;k<=m;k++){ans.mx[k]=max(a.mx[k],b.mx[k]);}return;
}
void build(int k,int l,int r){if(l==r){for(int i=1;i<=m;i++){tr[k].dp[i]=tr[k].mx[i]=T[dfn[l]][i];}return;}build(ls,l,mid);build(rs,mid+1,r);merge(tr[ls],tr[rs],tr[k]);
}
void change(int k,int l,int r,int x,bag o){if(l==r){tr[k]=o;return;}if(x<=mid) change(ls,l,mid,x,o);else change(rs,mid+1,r,x,o);merge(tr[ls],tr[rs],tr[k]);
}
bag ask(int k,int l,int r,int x,int y){//  printf("k=%d l=%d r=%d x=%d y=%d\n",k,l,r,x,y);if(x<=l&&r<=y) return tr[k];if(y<=mid) return ask(ls,l,mid,x,y);else if(x>mid) return ask(rs,mid+1,r,x,y);bag o;merge(ask(ls,l,mid,x,y),ask(rs,mid+1,r,x,y),o);return o;
}
const int X=1<<16,Y=(1ll<<31)-1;
inline int getint(){A=((A^B)+B/X+B*X)&Y;B=((A^B)+A/X+A*X)&Y;return (A^B)%Q;
}
bag query(int x,int f){bag o;memset(o.dp,0,sizeof(o.dp));memset(o.mx,0,sizeof(o.mx));while(top[x]!=top[f]){merge(o,ask(1,1,n,pos[top[x]],pos[x]),o);x=fa[top[x]];}merge(o,ask(1,1,n,pos[f],pos[x]),o);return o;
}
int main(){//cout<<X<<" "<<Y;memset(fi,-1,sizeof(fi));cnt=-1;n=read();m=read();A=read();B=read();Q=read();for(int i=2;i<=n;i++){int x=read();addline(x,i);}dfs1(1,0);dfs2(1,1);
//  for(int i=1;i<=n;i++) printf("i=%d fa=%d pos=%d siz=%d hson=%d\n",i,fa[i],pos[i],siz[i],hson[i]);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) T[i][j]=getint();sort(T[i]+1,T[i]+1+m);}build(1,1,n);int q=read();for(int o=1;o<=q;o++){int f=read();if(f==0){int p=read();bag now;for(int i=1;i<=m;i++) now.dp[i]=getint();now.dp[0]=0;sort(now.dp+1,now.dp+1+m);for(int i=1;i<=m;i++) now.mx[i]=now.dp[i];change(1,1,n,pos[p],now);}else{int u=read(),v=read();bag ans=ask(1,1,n,pos[u],pos[u]+siz[u]-1);ll res=0;if(u==v) printf("%lld\n",ans.dp[m]);else{bag mx=query(fa[u],v);for(int i=m;i>=0;i--) ans.dp[m]=max(ans.dp[m],ans.dp[i]+mx.mx[m-i]);printf("%lld\n",ans.dp[m]);}}}return 0;
}
/*
*/

YBTOJ:采矿战略(线段树维护dp、树链剖分)相关推荐

  1. Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp

    D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...

  2. 【BZOJ2164】采矿 树链剖分+线段树维护DP

    [BZOJ2164]采矿 Description 浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略.这个城市可以看成一棵有n个节点的有根树,我们把每个节点用1到n ...

  3. P3899 [湖南集训]更为厉害(线段树合并、长链剖分、二维数点)

    P3899 [湖南集训]更为厉害 若 deepb<deepa\text{deep}_b<\text{deep}_adeepb​<deepa​:c 在点 a 的子树中,根据乘法原理计算 ...

  4. [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分

    题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...

  5. P3565 [POI2014]HOT-Hotels(树形dp+长链剖分)

    P3565 [POI2014]HOT-Hotels 参考题解 题目大意: 给定一棵树,在树上选 3 个点,要求两两距离相等,求方案数. 三个点树上两两距离为d存在下面两种情况 某个点三个子树(保证该点 ...

  6. 兰州大学第一届 飞马杯 ★★飞马祝福语★★ 线段树维护dp(动态dp)

    传送门 文章目录 题意: 思路: 题意: 给你一个串,每次将区间都修改为某一个字母,问最终包含多少个FeiMaFeiMaFeiMa子序列. 思路: 首先暴力修改肯定是不行的,复杂度nqnqnq. 如果 ...

  7. [动态dp]线段树维护转移矩阵

    背景:czy上课讲了新知识,从未见到过,总结一下. 所谓动态dp,是在动态规划的基础上,需要维护一些修改操作的算法. 这类题目分为如下三个步骤:(都是对于常系数齐次递推问题) 1先不考虑修改,不考虑区 ...

  8. 线段树 ---- Codeforces 737 Div2 D. Ezzat and Grid 维护dp

    题目链接 题目大意: 就是给你很多行的010101串,长度是1e91e91e9,每一行都有若干段的连续的111,对于给定的串集合是美丽的美丽的美丽的的条件是任意相邻两行的串至少有一个列是同时有111的 ...

  9. 【2019牛客暑期多校训练营(第二场)- E】MAZE(线段树优化dp,dp转矩阵乘法,线段树维护矩阵乘法)

    题干: 链接:https://ac.nowcoder.com/acm/contest/882/E?&headNav=acm 来源:牛客网 Given a maze with N rows an ...

最新文章

  1. php 中find,Linux中find命令的用法汇总
  2. 其他算法-Dijkstra
  3. oracle数据库函数和存储过程的包
  4. python六十一: __module__属性
  5. Qt中的QFileDialog类的几个示范代码
  6. 从零开始的服务器配置
  7. 数据网格组件 Handsontable 不再开源,采用自拟的非商业许可证
  8. 《HBase权威指南》读书笔记 第八章:架构,HFile格式
  9. 中国环境统计年鉴(2000到2018年)
  10. 记某次“静态浮动路由+urpf导致”网络故障排查
  11. OSChina 周六乱弹 ——我的闺蜜是总统
  12. 正确修改SATA模式
  13. 线性约束最小方差准则
  14. 连获国际大奖创下史上第一,这家耳机品牌凭什么与众不同?
  15. CC2530 + RFX2401C Zigbee模块
  16. 可以免费打电话的网站
  17. 吴恩达的2022年终盘点:生成式AI、ViT、大模型
  18. 回溯法求解0-1背包问题
  19. 走过了十年,亚信安全用什么引领云安全发展?
  20. js获取浏览器和设备相关宽度和高度

热门文章

  1. 大数据|意不意外?今年卖得最好的月饼是这个馅的……
  2. 数据挖掘算法之决策树算法总结
  3. java密码学原型算法_java密码学原型算法实现——双线性对.pdf
  4. ORACLE数据加载加本,使用oracle sqlldr加载数据
  5. 计算机二级链表,计算机二级c语言上机考试——结构体与链表(3页)-原创力文档...
  6. 织梦手机版list.php,解决织梦一级目录作域名list.php无法跳转到手机站的问题
  7. tcp unity 图片_用 Unity 做个游戏(七) - TCP Socket 客户端
  8. PAT乙级题目——1002写出这个数
  9. 数据结构——二叉树的非递归算法
  10. 上海市二级c语言软件环境,上海市计算机二级C语言复习资料 word整理版.doc