bzoj 2164: 采矿
Description
浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略。这个城市可以看成一棵有n个节点的有根树,我们把每个节点用1到n的整数编号。为了方便起见,对于任何一个非根节点v,它任何一个祖先的编号都严格小于v。树上的每个节点表示一个矿点,每条边表示一条街道。作为cg大军的一个小队长,你拥有m个部下。你有一张二维的动态信息表,用Ti,j表示第i行第j列的数据。当你被允许开采某个区域时,你可以将你的部下分配至各个矿点。在第i个矿点安排j个人可以获得Ti,j单位的矿产。允许开采的区域是这样描述的:给你一对矿点(u,v),保证v是u的祖先(这里定义祖先包括u本身);u为你控制的区域,可以在以u为根的子树上任意分配部下;u到v的简单路径(不包括u但包括v,若u=v则包括u)为探险路径,在该路径上你可以选择至多一个矿点安排部下。你这次开采的收益为安排有部下的矿点的收益之和。
Solution
对于子树维护一个背包数组, \(f[i]\) 表示取 \(i\) 个的最大收益,链上维护一个 \(max\)
把子树内的合并,链上的不合并,分别维护即可
线段树查询子树,树链剖分查询一下路径 \((x,y)\) 上的点即可
#include<bits/stdc++.h>
#define ls (o<<1)
#define rs (o<<1|1)
using namespace std;
template<class T>void gi(T &x){
int f;char c;
for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
}
typedef long long ll;
const int N=20010,M=55;
int n,m,A,B,Q,fa[N],head[N],nxt[N],to[N],num=0,son[N],dep[N];
int sz[N],L[N],R[N],ID=0,top[N],b[N],X=1<<16,Y=(1ll<<31)-1;
struct data{ll f[M];
inline void init(){memset(f,0,sizeof(f));}
}tr[N*4],te[N*4],E,a[N],t0;
inline data operator +(data p,data q){
for(int i=0;i<=m;i++)p.f[i]=max(p.f[i],q.f[i]);
return p;
}
inline data operator *(data p,data q){
data ret;ret.init();
for(int i=0;i<=m;i++)
for(int j=0;i+j<=m;j++)ret.f[i+j]=max(ret.f[i+j],p.f[i]+q.f[j]);
return ret;
}
inline int getint(){
A=((A^B)+B/X+B*X)&Y;
B=((A^B)+A/X+A*X)&Y;
return (A^B)%Q;
}
inline void get(){
for(int i=1;i<=m;i++)E.f[i]=getint();
sort(E.f+1,E.f+m+1);
}
inline void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
inline void dfs1(int x){
sz[x]=1;
for(int i=head[x],u;i;i=nxt[i]){
if((u=to[i])==fa[x])continue;
dep[u]=dep[x]+1;dfs1(u);sz[x]+=sz[u];
if(sz[u]>sz[son[x]])son[x]=u;
}
}
inline void dfs2(int x,int tp){
b[L[x]=++ID]=x;top[x]=tp;
if(son[x])dfs2(son[x],tp);
for(int i=head[x];i;i=nxt[i])
if(to[i]!=fa[x] && to[i]!=son[x])dfs2(to[i],to[i]);
R[x]=ID;
}
inline void upd(int o){tr[o]=tr[ls]+tr[rs],te[o]=te[ls]*te[rs];}
inline void build(int l,int r,int o){
if(l==r){tr[o]=te[o]=a[b[l]];return ;}
int mid=(l+r)>>1;
build(l,mid,ls);build(mid+1,r,rs);
upd(o);
}
inline void mdf(int l,int r,int o,int sa){
if(l==r){tr[o]=te[o]=E;return ;}
int mid=(l+r)>>1;
if(sa<=mid)mdf(l,mid,ls,sa);
else mdf(mid+1,r,rs,sa);
upd(o);
}
inline data qr(int l,int r,int o,int sa,int se){
if(sa<=l && r<=se)return tr[o];
int mid=(l+r)>>1;
if(se<=mid)return qr(l,mid,ls,sa,se);
if(sa>mid)return qr(mid+1,r,rs,sa,se);
return qr(l,mid,ls,sa,mid)+qr(mid+1,r,rs,mid+1,se);
}
inline data qe(int l,int r,int o,int sa,int se){
if(sa<=l && r<=se)return te[o];
int mid=(l+r)>>1;
if(se<=mid)return qe(l,mid,ls,sa,se);
if(sa>mid)return qe(mid+1,r,rs,sa,se);
return qe(l,mid,ls,sa,mid)*qe(mid+1,r,rs,mid+1,se);
}
inline data solve(int x,int y){
data ret;ret.init();
if(x==y)return ret;
x=fa[x];
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ret=ret+qr(1,n,1,L[top[x]],L[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
ret=ret+qr(1,n,1,L[x],L[y]);
return ret;
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
cin>>n>>m>>A>>B>>Q;
for(int i=2;i<=n;i++)gi(fa[i]),link(fa[i],i);
dfs1(1);dfs2(1,1);
for(int i=1;i<=n;i++)get(),a[i]=E;
build(1,n,1);
int C,op,x,y;
cin>>C;
while(C--){
gi(op);gi(x);
if(op==0)get(),mdf(1,n,1,L[x]);
else{
gi(y);
t0=qe(1,n,1,L[x],R[x])*solve(x,y);
printf("%lld\n",t0.f[m]);
}
}
return 0;
}
bzoj 2164: 采矿的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 树形dp专题总结
树形dp专题总结 大力dp的练习与晋升 原题均可以在网址上找到 技巧总结 1.换根大法 2.状态定义应只考虑考虑影响的关系 3.数据结构与dp的合理结合(T11) 4.抽直径解决求最长链的许多类问题( ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
随机推荐
- C#高级特性:动态绑定
C#高级特性:动态绑定 动态绑定 动态绑定将类型绑定(类型解析.成员和操作过程)从编译时推迟到了运行时.在编译时,如果程序员知道某个特定函数.成员的存在而编译器不知道,那么这种操作是非常有用的,这种情 ...
- uni-app开发踩坑记录
大部分问题是我在h5端看不到而在android.iOS平台上暴露出来的,不包含小程序 1.:class="['defaultStyle', dynamicStyle]" 不支持直接 ...
- 关于.NET C#调用Sqlite的总结二
关于.NET C#调用Sqlite的总结一 在上一篇中我一直疑惑为什么我在使用多层架构进行开发时总是会报些莫名的错误,难道要使用Sqlite就不能分层吗?只能将UI.业务逻辑.数据访问统统都要写在一层 ...
- centos7 minimal 安装mysql
CentOS 7.3.1611 安装 MySQL 2017年06月08日 23:02:08 阅读数:250 依赖 MySQL 依赖 libaio,所以先要安装 libaio yum search ...
- Windows server 2008 R2安装MySQL 32位ODBC驱动!
在Windows server 2008 R2安装MySQL 32位ODBC驱动,总是提示错误,我安装了DOTNET4的库,同时安装了VC2008.VC2012.VC2013的支持库,怎么还不行呢?M ...
- “全栈2019”Java第八十三章:内部类与接口详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 案例1-合并2个不同文件夹中的csv文件到另外一个目录,相同的文件名进行数据合并,不同的文件名直接移到新文件夹
发现在ubuntu和centos中有些命令还不一样,比如<<<可在centos中使用,但是ubuntu中不行 csv文件名以及格式如下 3669_20180121.csv 总笔数,2 ...
- 队列优化dijsktra(SPFA)的玄学优化
转载:大佬博客 最近想到了许多优化spfa的方法,这里想写个日报与大家探讨下 前置知识:spfa(不带任何优化) 由于使用较多 STLSTL ,本文中所有代码的评测均开启 O_2O2 优化 对一些数 ...
- 使用Avd 调试慢的解决方案
AVD 太慢了,不仅启动,而且运行慢.以致于要用手机去调.你觉得这样方便吗? 如果没有一个简单快速的开发调试环境,把时间都浪费在启动,调试及等待上,那是对生命的浪费. 必要条件: ...
- 2016级算法第四次上机-A.Bamboo 和人工zz
Bamboo和人工ZZ 题意: 非常直白,经典的动态规划矩阵链乘问题 分析: 矩阵链A1A2..An满足结合律,可以使用加括号的方式,降低运算代价. 一个pq的矩阵和一个qr的矩阵相乘,计算代价为pq ...