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;
}