求助大佬,左偏树,WA
查看原帖
求助大佬,左偏树,WA
544860
linyihdfj楼主2022/6/19 08:15

原本写的 dfs,后面用的题解写的循环写法,但是没啥用,都是 WA

#include<bits/stdc++.h>
using namespace std;
const long long MAXN = 6e5+5;
struct edge{
	long long nxt,to;
	edge(){}
	edge(long long _nxt,long long _to){
		nxt = _nxt,to = _to;
	}
}e[MAXN];
long long cnt,head[MAXN],dep[MAXN],die[MAXN],ans[MAXN],rt[MAXN],dist[MAXN],ls[MAXN],add[MAXN],times[MAXN],rs[MAXN],s[MAXN],c[MAXN],h[MAXN],a[MAXN],fa[MAXN],v[MAXN];
void pushdown(long long now){
	if(ls[now]){
		times[ls[now]] *= times[now];
		add[ls[now]]*=times[now];
		add[ls[now]]+=add[now];
		s[ls[now]]*=times[now];   //因为 add 已经乘过了,所以如果先加再乘那么就会多乘一次 
		s[ls[now]]+=add[now];
	}
	if(rs[now]){
		times[rs[now]] *= times[now];
		add[rs[now]]*=times[now];
		add[rs[now]]+=add[now];
		s[rs[now]]*=times[now];   
		s[rs[now]]+=add[now];
	}
	times[now] = 1;
	add[now] = 0;
}
long long merge(long long x,long long y){
	if(!x || !y)	return x + y; 
	pushdown(x);pushdown(y); 
	if(s[x] > s[y])	 swap(x,y);  //维护一个小根堆 
	rs[x] = merge(rs[x],y);  //左偏,所以这样可以尽可能平均 
	if(dist[ls[x]] < dist[rs[x]])	swap(ls[x],rs[x]); 
        dist[x] = dist[rs[x]] + 1;     
	return x; 
}
void add_edge(long long from,long long to){
	e[++cnt] = edge(head[from],to);
	head[from] = cnt;
}
int main(){
	long long n,m;
	cin>>n>>m;
	for(long long i=1; i<=n; i++){
		cin>>h[i];
		rt[i] = -1;
	}
	dep[1] = 1;dist[0] = -1;  //一定要记得 dep[1] = 1,不要 dep[1]=0,因为如果只是打过了 1 也算是占领一座 
	for(long long i=2; i<=n; i++){
		cin>>fa[i]>>a[i]>>v[i];
		dep[i] = dep[fa[i]] + 1;
	}
	for(long long i=1; i<=m; i++){
		times[i] = 1;
		cin>>s[i]>>c[i];
		if(rt[c[i]] == -1)	rt[c[i]] = i;
		else	rt[c[i]] = merge(rt[c[i]],i);
	}
	for(int i=n; i>=1; i--){  //根据题目性质 
		while(rt[i]!=-1){
			if(h[i] > s[rt[i]]){
				die[rt[i]] = i;
				pushdown(rt[i]);
				if(!ls[rt[i]])	rt[i] = -1;
				else	rt[i] = merge(ls[rt[i]],rs[rt[i]]);
			}
			else
				break;
		}
		if(i == 1)	break;
		if(rt[i] == -1)	continue;
		if(a[i] == 1){
			s[rt[i]]*=v[i];add[rt[i]]*=v[i];times[rt[i]]*=v[i];
		}
		else{
			add[rt[i]]+=v[i];s[rt[i]]+=v[i];
		}
		pushdown(rt[i]);
		if(rt[fa[i]] == -1)	rt[fa[i]] = rt[i];
		else	rt[fa[i]] = merge(rt[fa[i]],rt[i]);
	}
	for(long long i=1; i<=m; i++){
		ans[die[i]]++;
	}
	for(long long i=1; i<=n; i++){
		printf("%lld\n",ans[i]);
	}
	for(long long i=1; i<=m; i++){
		printf("%lld\n",dep[c[i]] - dep[die[i]]);
	}
	return 0;
}
2022/6/19 08:15
加载中...