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: 采矿的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. 树形dp专题总结

    树形dp专题总结 大力dp的练习与晋升 原题均可以在网址上找到 技巧总结 1.换根大法 2.状态定义应只考虑考虑影响的关系 3.数据结构与dp的合理结合(T11) 4.抽直径解决求最长链的许多类问题( ...

  3. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  4. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  5. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  6. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  7. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  8. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

  9. 【清华集训】楼房重建 BZOJ 2957

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...

随机推荐

  1. WPF MaterialDesignInXamlToolkit锁屏恢复后页面冻结的问题

    在做WPF项目时,用到 MaterialDesignInXamlToolkit 开源项目.结果客户用的时候发现这个问题,锁屏后,界面不刷新. 如果不用MaterialDesign,测试后不会出现这个问 ...

  2. cannot be resolved to a type (Java)

    最近经常遇到cannot be resolved to a type (Java)报错,以下为在网上找到的解决方案: 1.先看看有没有引用相关jar包2.检查jar是否引用了多个相同的,或者多个jar ...

  3. [BJ2006] 狼抓兔子

    题目链接:戳我 按理说以dinic\(O(M*N^2)\)的时间复杂度应该是过不去的(呃我也知道这个上界很松).但是最小割确实可以水过去?? 但是本着写正解的精神,我还是学了学平面图和对偶图,跑最短路 ...

  4. 201621123023《Java程序设计》第2周学习总结

    一. 本周学习总结 引用类型变量存放指向对象的引用(类似于地址): == 与 equals 区别在于:==比较的是引用是否相等, 而equals则比较指向对象的内容是否相等: 因为String的不可变 ...

  5. git 分支同步master最新代码

    查看分支:git branch创建分支:git branch <name>切换分支:git checkout <name>创建+切换分支:git checkout -b < ...

  6. python 特性:height-->while

    """ 出题:height 女生找对象 男生在1米-1.5米之间 小强你在哪里? 男生在1.5-1.7米之间 没有安全感 男生在1.7 - 1.8米之间 帅哥 留个电话 ...

  7. kvm虚拟化之kvm虚拟机vnc配置

    本文是通过vnc方式访问虚拟主机上的KVM虚拟机.    这里的通过vnc方式访问虚拟机不是在kvm虚拟机安装配置vnc服务器,通过虚拟主机的IP地址与端口进行访问,kvm虚拟化对vnc的支持相对来说 ...

  8. TCP/IP学习笔记(2)-数据链路层

    数据链路层有三个目的: 为IP模块发送和接收IP数据报. 为ARP模块发送ARP请求和接收ARP应答. 为RARP发送RARP请求和接收RARP应答 ip大家都听说过.至于ARP和RARP,ARP叫做 ...

  9. [Flex] 组件Tree系列 —— 运用LabelFunction hasChildren getChildren设置Tree包含节点个数

    mxml: <?xml version="1.0" encoding="utf-8"?> <!--功能描述:运用LabelFunction h ...

  10. 生产环境elasticsearch

    生产环境建议用curl来调用elasticsearch的restful接口来创建索引,每个索引的index脚本,mapping的脚本都提前写好提到git上打包,部署的时候直接通过curl执行 开发环境 ...