CF1178G The Awesomest Vertex
作者:互联网
前言
思维量还可以(也挺大的)但是代码量巨大(写起来特别不舒服)的又一道神仙题。
正文
题目大意:一棵树 \(n\) 个节点,以 \(1\) 为根,每个节点有两个属性 \((a,b)\),\(R(v)\) 为 \(v\) 的祖先(包括自己):
\[|\sum_{u\in R(v)}a_u|\cdot|\sum_{u\in R(v)}b_u| \]需要支持:
- 将 \(a_v\) 加上 \(x\)。
- 查询 \(v\) 的子树里最大值。
数据范围:\(n\leq 2\cdot 10^5,q\leq 10^5\)
思路比较简单。
考虑将 \(|\sum a|\) 拆成 \(\max(\sum a,-\sum a)\),\(b_i\) 可以预处理。
然后你看到柿子形式 \(\Delta x\cdot b+ab\) 直接斜率优化维护凸壳。
凸壳放在线段树里合并即可。
主要还是代码难写QAQ。
#include <bits/stdc++.h>
#define sz(x) (int)(x.size())
using namespace std;
const int mod=1e9+7,Base=233,inf=0x3f3f3f3f;
const long long INF=0x3f3f3f3f3f3f3f3f;
template<typename T>inline void chmax(T &a, T b){a=max(a,b);}
template<typename T>inline void chmin(T &a, T b){a=min(a,b);}
inline void trans(int &a,int b){a+=b;if(a>mod)a-=mod;}
const int maxn=4e5+5;
int n,q,p[maxn];
long long a[maxn],b[maxn];
vector<int> g[maxn];
int in[maxn],out[maxn],tim=0;
long long ne[maxn<<2],d[maxn<<2];
struct line
{
long long k,b;
}val[maxn];
struct node
{
int l,r;
long long k,b;
};
struct segtree
{
node tree[maxn<<2];
void pushup(int x)
{
int v=(tree[x<<1].b>=tree[x<<1|1].b?(x<<1):(x<<1|1));
tree[x].k=tree[v].k;
tree[x].b=tree[v].b;
ne[x]=min((tree[v].k>=tree[v^1].k?INF:(tree[v].b-tree[v^1].b)/(tree[v^1].k-tree[v].k)),min(ne[x<<1],ne[x<<1|1]));
}
void upd(int x,long long v)
{
tree[x].b+=tree[x].k*v;
ne[x]-=v;
d[x]+=v;
}
void pushdown(int x)
{
if(!d[x])
return;
upd(x<<1,d[x]);
upd(x<<1|1,d[x]);
d[x]=0;
}
void build(int x,int l,int r)
{
tree[x].l=l;
tree[x].r=r;
if(l==r)
{
tree[x].k=val[l].k;
tree[x].b=val[l].b;
ne[x]=INF;
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
void update(int x,int l,int r,long long v)
{
if(!tree[x].r)
return;
if(tree[x].l>=l&&tree[x].r<=r&&v<=ne[x])
{
upd(x,v);
return;
}
pushdown(x);
int mid=(tree[x].l+tree[x].r)>>1;
if(l<=mid)
update(x<<1,l,r,v);
if(r>mid)
update(x<<1|1,l,r,v);
pushup(x);
}
long long query(int x,int l,int r)
{
if(tree[x].l>=l&&tree[x].r<=r)
return tree[x].b;
pushdown(x);
int mid=(tree[x].l+tree[x].r)>>1;
long long ret=-INF;
if(l<=mid)
ret=query(x<<1,l,r);
if(r>mid)
chmax(ret,query(x<<1|1,l,r));
return ret;
}
}tr;
void dfs(int u)
{
in[u]=++tim;
a[u]+=a[p[u]];
b[u]+=b[p[u]];
long long v=abs(b[u]);
val[tim]={v,a[u]*v};
for(int i=0;i<sz(g[u]);i++)
{
int v=g[u][i];
dfs(v);
}
out[u]=++tim;
val[tim]={-v,-a[u]*v};
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=2;i<=n;i++)
{
scanf("%d",p+i);
g[p[i]].push_back(i);
}
for(int i=1;i<=n;i++)
scanf("%lld",a+i);
for(int i=1;i<=n;i++)
scanf("%lld",b+i);
dfs(1);
tr.build(1,1,tim);
int opt,v;
long long x;
while(q--)
{
scanf("%d%d",&opt,&v);
if(opt==1)
{
scanf("%lld",&x);
tr.update(1,in[v],out[v],x);
}
else
{
printf("%lld\n",tr.query(1,in[v],out[v]));
}
}
return 0;
}
标签:Awesomest,const,int,tree,sum,Vertex,long,CF1178G,maxn 来源: https://www.cnblogs.com/Jerry-Jiang/p/16576448.html