其他分享
首页 > 其他分享> > CF1178G The Awesomest Vertex

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| \]

需要支持:

数据范围:\(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