UOJ 上能过洛谷上过不了求助
查看原帖
UOJ 上能过洛谷上过不了求助
754467
f_hxr_楼主2025/6/20 17:12

rt,UOJ上一发就过了。然而在洛谷上不管怎么交都没法过。样例也都过了。疑似输出答案时判无解是出了问题(全都输出 0)。所以怀疑是线段树出了问题。

有无大佬指出合并或懒标记下传的 Bug 或给个 Hack 啊话说官方数据在哪下啊

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=5e5+7;
int N,Q,a[maxn],inx[maxn];
struct NODE{
	//和,最小值,数量,答案
	LL sum,mn,num;
	LL addv,bddv;//两个标记 
}dat[maxn<<2];
NODE operator + (NODE A,NODE B){
	NODE ret;
	if(A.mn==B.mn){
		ret.sum=A.sum+B.sum;
		ret.mn=A.mn;
		ret.num=A.num+B.num;
	}else if(A.mn<B.mn){
		ret.sum=A.sum;
		ret.mn=A.mn;
		ret.num=A.num;
	}else{
		ret.sum=B.sum;
		ret.mn=B.mn;
		ret.num=B.num;
	}
	return ret;
}
inline void pushup(int p){dat[p]=dat[p<<1]+dat[p<<1|1];}
void build(int p,int L,int R){
	if(L>=R){
		dat[p].sum=0;
		dat[p].mn=1-L;
		dat[p].num=1;
		return;
	}
	int mid=(L+R)>>1;
	build(p<<1,L,mid);build(p<<1|1,mid+1,R);
	pushup(p);
}
inline void AddTag(int p,LL xx){
	dat[p].mn+=xx;
	dat[p].addv+=xx;
}
inline void BddTag(int p,LL xx){
	dat[p].sum+=xx*dat[p].num;
	dat[p].bddv+=xx;
}
inline void pushdown(int p){
	if(dat[p].addv){
		AddTag(p<<1,dat[p].addv);
		AddTag(p<<1|1,dat[p].addv);
		dat[p].addv=0;
	}
	if(dat[p].bddv){
		BddTag(p<<1,dat[p].bddv);
		BddTag(p<<1|1,dat[p].bddv);
		dat[p].bddv=0;
	}
}
void Add(int p,int L,int R,int ql,int qr,LL xx){
	if(ql<=L&&R<=qr){AddTag(p,xx);return;}
	int mid=(L+R)>>1;pushdown(p);
	if(ql<=mid)Add(p<<1,L,mid,ql,qr,xx);
	if(mid+1<=qr)Add(p<<1|1,mid+1,R,ql,qr,xx);
	pushup(p);
}
void Bdd(int p,int L,int R,int ql,int qr,LL xx){
	if(ql<=L&&R<=qr){BddTag(p,xx);return;}
	int mid=(L+R)>>1;pushdown(p);
	if(ql<=mid)Bdd(p<<1,L,mid,ql,qr,xx);
	if(mid+1<=qr)Bdd(p<<1|1,mid+1,R,ql,qr,xx);
	pushup(p);
}
inline void AddEdge(int u,int v,LL xx){
	u=inx[u];v=inx[v];
	int l=min(u,v),r=max(u,v);
	Add(1,1,N-1,l,N-1,xx);
	Bdd(1,1,N-1,l,r-1,xx);
}
int U[maxn],V[maxn];
int main(){
	scanf("%d %d",&N,&Q);
	for(int i=1;i<N;i++)scanf("%d %d",&U[i],&V[i]);
	for(int i=1;i<N;i++)scanf("%d",&a[i]),inx[a[i]]=i;
	inx[1]=N;
	build(1,1,N-1);
	for(int i=1;i<N;i++)AddEdge(U[i],V[i],1);
	printf("%lld\n",(dat[1].mn==1)?dat[1].sum:0);
	while(Q--){
		int u1,v1,u2,v2;scanf("%d %d %d %d",&u1,&v1,&u2,&v2);
		AddEdge(u1,v1,-1);
		AddEdge(u2,v2,1);
		printf("%lld\n",(dat[1].mn==1)?dat[1].sum:0);
	}
	return 0;
}
2025/6/20 17:12
加载中...