BZOJ2164 : 采矿

树链剖分+线段树,每个节点维护以下信息:

(1)单独在某个点分配$i$个人的最大收益。可以$O(m)$合并。

(2)分配$i$个人的最大收益。可以用$O(m^2)$合并。

时间复杂度$O(c(m^2\log n+m\log^2n))$。

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=20010,M=51,T=65600;
int n,m,q,X=1<<16,Y=~0U>>1,A,B,Q,i,op,x,y;
int g[N],nxt[N],f[N],d[N],size[N],son[N],st[N],en[N],top[N],seq[N],dfn;
struct P{
  ll v[M];
  P(){for(int i=0;i<M;i++)v[i]=0;}
  P operator+(P b){
    P c;
    for(int i=0;i<M;i++)c.v[i]=max(v[i],b.v[i]);
    return c;
  }
  P operator*(P b){
    P c;
    for(int i=0;i<M;i++)for(int j=0;j<M-i;j++)c.v[i+j]=max(c.v[i+j],v[i]+b.v[j]);
    return c;
  }
}tmp,a[N],v0[T],v1[T],s0,s1;
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 gettmp(){
  for(int i=1;i<=m;i++)tmp.v[i]=getint();
  sort(tmp.v+1,tmp.v+m+1);
}
void dfs(int x){
  size[x]=1;
  for(int i=g[x];i;i=nxt[i]){
    d[i]=d[x]+1,dfs(i),size[x]+=size[i];
    if(size[i]>size[son[x]])son[x]=i;
  }
}
void dfs2(int x,int y){
  seq[st[x]=++dfn]=x;top[x]=y;
  if(son[x])dfs2(son[x],y);
  for(int i=g[x];i;i=nxt[i])if(i!=son[x])dfs2(i,i);
  en[x]=dfn;
}
inline void up(int x){
  v0[x]=v0[x<<1]+v0[x<<1|1];
  v1[x]=v1[x<<1]*v1[x<<1|1];
}
void build(int x,int a,int b){
  if(a==b){v0[x]=v1[x]=::a[seq[a]];return;}
  int mid=(a+b)>>1;
  build(x<<1,a,mid),build(x<<1|1,mid+1,b),up(x);
}
void change(int x,int a,int b,int c){
  if(a==b){v0[x]=v1[x]=tmp;return;}
  int mid=(a+b)>>1;
  if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c);
  up(x);
}
void ask0(int x,int a,int b,int c,int d){
  if(c<=a&&b<=d){s0=s0+v0[x];return;}
  int mid=(a+b)>>1;
  if(c<=mid)ask0(x<<1,a,mid,c,d);
  if(d>mid)ask0(x<<1|1,mid+1,b,c,d);
}
void ask1(int x,int a,int b,int c,int d){
  if(c<=a&&b<=d){s1=s1*v1[x];return;}
  int mid=(a+b)>>1;
  if(c<=mid)ask1(x<<1,a,mid,c,d);
  if(d>mid)ask1(x<<1|1,mid+1,b,c,d);
}
inline void chain(int x,int y){
  if(x==y)return;
  x=f[x];
  while(top[x]!=top[y])ask0(1,1,n,st[top[x]],st[x]),x=f[top[x]];
  ask0(1,1,n,st[y],st[x]);
}
int main(){
  scanf("%d%d%d%d%d",&n,&m,&A,&B,&Q);
  for(i=2;i<=n;i++)scanf("%d",&f[i]),nxt[i]=g[f[i]],g[f[i]]=i;
  for(i=1;i<=n;i++)gettmp(),a[i]=tmp;
  dfs(1),dfs2(1,1),build(1,1,n);
  scanf("%d",&q);
  while(q--){
    scanf("%d%d",&op,&x);
    if(!op)gettmp(),change(1,1,n,st[x]);
    else{
      scanf("%d",&y);
      s0=s1=P();
      chain(x,y),ask1(1,1,n,st[x],en[x]);
      s0=s0*s1;
      printf("%lld\n",s0.v[m]);
    }
  }
  return 0;
}

  

时间: 2025-01-04 23:47:35

BZOJ2164 : 采矿的相关文章

Bzoj2164 采矿(线段树+树链剖分)

题面 Bzoj 题解 对于每个节点,我们可以用树链剖分和线段树维护以下信息: 单独在某个点分配\(i\)个人的最大收益(可以\(O(m)\)计算) 分配\(i\)的最大收益(可以\(O(m^2)\)计算) #include <cstdio> #include <cstring> #include <algorithm> using std::min; using std::max; using std::sort; using std::swap; typedef lo

&nbsp; 为什么采矿行业会成为网络攻击的目标?

矿业经济因素:矿业经济是影响国家经济的一个关键因素,当然,随之而来的也可能有网络攻击.下图显示了部分国家对国民经济占有重要地位的主要出口项目,其中矿业行业为出口支柱行业. 为什么采矿行业会成为网络攻击的目标? 一, 获取有竞争优势的最新技术知识和情报 针对采矿行业的网络间谍活动主要是为了确保利益集团获得最新的技术知识和情报,使他们能够保持竞争优势,并在全球大宗商品交易市场中蓬勃发展. (1) 对金属和矿产的定价数据是网络间谍活动针对矿业行业的窃取目标之一.如果对手拥有矿业内幕定价数据信息就可以在

洛谷P2380 狗哥采矿

P2380 狗哥采矿 题目背景 又是一节平静的语文课 狗哥闲来无事,出来了这么一道题 题目描述 一个n*m的矩阵中,每个格子内有两种矿yeyenum和bloggium,并且知道它们在每个格子内的数量是多少.最北边有bloggium的收集站,最西边有 yeyenum 的收集站.现在要你在这些格子上面安装向北或者向西的传送带(每个格子只能装一种).问最多能采到多少矿? 输入输出格式 输入格式: 第一行包含两个整数n,m,( 1 ≤ n ≤ 500, 1 ≤ m ≤ 500).接下来n行m列,表示每个

【弱校胡策】2016.4.14 (bzoj2164)最短路+状压DP+矩阵乘法+高斯消元+树链剖分+线段树+背包DP

cyyz&qhyz&lwyz&gryz弱校胡策 命题人:cyyz ws_fqk T3暴力写挫了 50+10+0滚粗辣! 奇妙的约会(appointment.cpp/c/pas) [问题描述] DQS和sxb在网上结识后成为了非常好的朋友,并且都有着惊人 的OI水平.在NOI2333的比赛中,两人均拿到了金牌,并保送进入 HU/PKU.于是两人决定在这喜大普奔的时刻进行面基. NOI2333参赛选手众多,所以安排了n个考点,DQS在1号考点, 而sxb在n号考点.由于是举办全国性赛事

bzoj 2164: 采矿

Description 浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略.这个城市可以看成一棵有n个节点的有根树,我们把每个节点用1到n的整数编号.为了方便起见,对于任何一个非根节点v,它任何一个祖先的编号都严格小于v.树上的每个节点表示一个矿点,每条边表示一条街道.作为cg大军的一个小队长,你拥有m个部下.你有一张二维的动态信息表,用Ti,j表示第i行第j列的数据.当你被允许开采某个区域时,你可以将你的部下分配至各个矿点.在第i个矿点安排j个人可以获得Ti

hdu 1173 采矿

水题,小白练手. 想法:即是最近距离,并且只允许走直线,x和y方向上就没太大关系,那就只考虑一维就够了,一维到一个点距离最近,2n个点中找一个最近距离,应该是二分点集任意区域都可以,这点可以用样例来证明下,两次找中心即得坐标: 代码: #include <iostream> #include <stdio.h> #include <algorithm> using namespace std; const int MAXN = 1000000+88; #define l

使用python读取txt坐标文件生成挖空矿山_采矿批量

# -*-coding:utf-8-*- import arcpy import fileinput import os # 采矿权坐标格式举例 # 1,3509447.04,37493933.70 # 2,3509447.05,37495583.71 # 3,3508597.04,37495583.72 # 4,3508597.04,37494783.71 # 5,3508336.97,37494583.71 # 6,3508247.03,37493933.70 # *,1300,-400,,

luogu 题解 P2380 【狗哥采矿】

拿到dp题我们就要想如何推方程 “最北边有bloggium的收集站,最西边有 yeyenum 的收集站.现在要你在这些格子上面安装向北或者向西的传送带(每个格子只能装一种).” 这说明了什么,对于某一个点,是不是只能通过2种方式来获取这个点的值,一个是铺北的传送带,一个是铺西的传送带.然而,如果在这个点铺了传送带的话,说明整一行都会被铺,但由于后来的可以铺不同的传送带来获取该点的值,说明如果在这个点铺的话只会影响这个点的西边的点或北边的点. 综上所述,我们对于仍以一个点,需要考虑以什么形式来铺,

2017年世界500强榜单,500强亏损公司,强最赚钱的50家公司

2017年世界500强榜单发布:腾讯阿里首次登榜 2017年07月20日 20:03:51 财富中文网于北京时间2017年7月20日晚与全球同步发布了最新的<财富>世界500强排行榜. 沃尔玛连续四年排名第一位,2016年营业收入达4,858.7亿美元,同比提升0.8%.前三阵营中的其它两家为中国公司--国家电网和中石化.中石油和丰田汽车分列第四和第五.唯一新进入前十阵营的是沃伦巴菲特掌管的保险和投资集团伯克希尔-哈撒韦公司.如今伯克希尔收入中近四分之三来自经营业务而非财务投资,在挣脱巴菲特光