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. SELinux导致无法访问外网,PHP连接MySQL异常Can't connect to MySQL server、redis程序访问提示Redis server went away的解决方法

    今天上班遇到的问题,新配的Linux服务器,php.Apache和一系列扩展插件装好后,在本地好好的程序移上去就一直抱数据库连接错误,而用sql命令却能连接上去, 做了一个简单的判断数据库连接页面还是 ...

  2. .NET Core + gRPC 实现数据串流 (Streaming)

    引入 gRPC 是谷歌推出的一个高性能优秀的 RPC 框架,基于 HTTP/2 实现.并且该框架对 .NET Core 有着优秀的支持.最近在做一个项目正好用到了 gRPC,遇到了需要串流传输的问题. ...

  3. Nginx使用

    1. 基本使用 分linux和windows版 windows版可以直接双击exe运行,默认配置为80端口,只有两个页面 html目录下为页面.css.js等代码文件 conf目录下为配置文件 主要的 ...

  4. 搜索下拉 select美化

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. linux校验时间

      一. 基本方法:date -s "2018-09-02 04:23:45"clock -w 把时间写入cmos(一个RAM芯片) hwclock 查看硬件时间 hwclock ...

  6. luogu P1518 两只塔姆沃斯牛 The Tamworth Two

    luogu P1518 两只塔姆沃斯牛 The Tamworth Two 题目描述 两只牛逃跑到了森林里.农夫John开始用他的专家技术追捕这两头牛.你的任务是模拟他们的行为(牛和John). 追击在 ...

  7. 条目二十四《当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择》

    条目二十四<当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择> 当效率至关重要时,应该在map::operator[]和map::insert之 ...

  8. C#-★结构体★

    结构体: 结构体类型是用户自己定义的一种类型,它是由其他类型组合而成的,可包含构造函数.常数.字段.方法.属性.索引器.运算符.事件和嵌套类型的值类型. 结构体在几个方面不同于类:结构体为值类型而不是 ...

  9. JAVA编译结果中有****$1.class的

    java编译后的文件名字带有$接数字的就是匿名内部类的编译结果,接名字的就是内部类的编译结果 例如:TestFrame$1.class是匿名内部类的编译结果,TestFrame$MyJob.class ...

  10. c++重载operator的示例 非原创

    #include<iostream> #include<vector> using namespace std; class test{ public: int v; /*构造 ...