P3261 [JLOI2015]城池攻占

思路

左偏树维护每个骑士的战斗力和加入的深度(因为只能向上跳)
注意做乘法的时候加法tag会受到影响

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long 
using namespace std;
struct Node{
	int lson,rson,dis,num,mul,add,add_dep,sz,fa,id;
}LT[300100];
int n,m,u[300100<<1],v[300100<<1],fir[300100],nxt[300100<<1],cnt,fa[300100],S[300100],C[300100],A[300100],V[300100],H[300100],root[300100],ans_city[300100],ans_man[300100],dep[300100];
int find(int x){
	if(LT[x].fa==x)
		return x;
	else 
		return LT[x].fa=find(LT[x].fa);
}
void pushup(int o){
	LT[o].sz=LT[LT[o].lson].sz+LT[LT[o].rson].sz+1;
}
void pushdown(int o){
	if(LT[o].mul!=1){
		LT[LT[o].lson].num*=LT[o].mul;
		LT[LT[o].rson].num*=LT[o].mul;
		LT[LT[o].lson].mul*=LT[o].mul;
		LT[LT[o].rson].mul*=LT[o].mul;
		LT[LT[o].lson].add*=LT[o].mul;
		LT[LT[o].rson].add*=LT[o].mul;
		LT[o].mul=1;
	} 
	if(LT[o].add){
		LT[LT[o].lson].num+=LT[o].add;
		LT[LT[o].rson].num+=LT[o].add;
		LT[LT[o].lson].add+=LT[o].add;
		LT[LT[o].rson].add+=LT[o].add;
		LT[o].add=0;
	}
}
int merge(int x,int y){
	if(x*y==0)
		return x+y;
	pushdown(x);
	pushdown(y);
	if(LT[x].num>LT[y].num)
		swap(x,y);
	LT[x].rson=merge(LT[x].rson,y);
	if(LT[LT[x].lson].dis<LT[LT[x].rson].dis)
		swap(LT[x].lson,LT[x].rson);
	LT[x].dis=LT[LT[x].rson].dis+1;
	LT[LT[x].lson].fa=LT[LT[x].rson].fa=LT[x].fa=x;
	pushup(x); 
	return x;
}
int pop(int u){
	pushdown(u); 
	LT[LT[u].lson].fa=LT[u].lson;
	LT[LT[u].rson].fa=LT[u].rson; 
	return LT[u].fa=merge(LT[u].lson,LT[u].rson);
}
void addedge(int ui,int vi){
	++cnt;
	u[cnt]=ui;
	v[cnt]=vi;
	nxt[cnt]=fir[ui];
	fir[ui]=cnt;
}
void dfs_dep(int u){
	dep[u]=dep[fa[u]]+1;
	for(int i=fir[u];i;i=nxt[i]){
		if(v[i]==fa[u])
			continue;
		dfs_dep(v[i]); 
	}
}
void dfs(int u){
	for(int i=fir[u];i;i=nxt[i]){
		if(v[i]==fa[u])
			continue;
		dfs(v[i]); 
		root[u]=merge(root[u],root[v[i]]);
	}	
	while(LT[root[u]].sz>=1&&LT[root[u]].num<H[u]){
		ans_city[u]++;
		ans_man[LT[root[u]].id]=LT[root[u]].add_dep-dep[u];
		root[u]=pop(root[u]);
	}
	if(A[u]){
		LT[root[u]].num*=V[u];
		LT[root[u]].mul*=V[u];
		LT[root[u]].add*=V[u];		
	}
	else {
		LT[root[u]].num+=V[u];
		LT[root[u]].add+=V[u];	
	}
}
void init(void){
	for(int i=1;i<=m;i++){
		LT[i].add_dep=dep[C[i]];
		LT[i].add=0;
		LT[i].mul=1;
		LT[i].id=i;
		LT[i].dis=1;
		LT[i].sz=1;
		LT[i].lson=LT[i].rson=0;
		LT[i].fa=i;
		LT[i].num=S[i];
		root[C[i]]=merge(root[C[i]],i);
	}
}
signed main(){
	scanf("%lld %lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&H[i]);
	}
	for(int i=2;i<=n;i++){
		scanf("%lld %lld %lld",&fa[i],&A[i],&V[i]);
		if(fa[i]){
			addedge(i,fa[i]);
			addedge(fa[i],i);
		}
	}
	for(int i=1;i<=m;i++){
		scanf("%lld %lld",&S[i],&C[i]);
	} 
	dfs_dep(1);
	init();
	dfs(1);
	while(LT[root[1]].sz>=1){
		ans_man[LT[root[1]].id]=LT[root[1]].add_dep;
		root[1]=pop(root[1]);
	}
	for(int i=1;i<=n;i++){
		printf("%lld\n",ans_city[i]);
	}
	for(int i=1;i<=m;i++) {
		printf("%lld\n",ans_man[i]);
	}
	return 0;
} 
posted @ 2019-03-17 12:04  dreagonm  阅读(134)  评论(0编辑  收藏  举报