提交时间:2024-08-29 16:46:03

运行 ID: 31997

#include<bits/stdc++.h> #define int long long using namespace std; int n,m,u,v,x,y,ia[500005],a[500005]; int num,hd[500005]; bitset<500005>b; int f[500005],g[500005]; struct P{int nxt,to;}line[1000006]; void add(int x,int y){ ++num; line[num]={hd[x],y}; hd[x]=num; return ; } struct Q{int l,r,sum,minn,num,tagf,tagg;}tree[2000006]; Q operator + (Q x,Q y){ Q z={x.l,y.r,0,min(x.minn,y.minn)}; if(x.minn==y.minn)z.sum=x.sum+y.sum,z.num=x.num+y.num; else if(x.minn<y.minn)z.sum=x.sum,z.num=x.num; else z.sum=y.sum,z.num=y.num; return z; } void build(int t,int l,int r){ tree[t].l=l,tree[t].r=r; if(l==r)return tree[t]={l,r,f[l],g[l],1},void(); int mid=l+r>>1; build(2*t,l,mid),build(2*t+1,mid+1,r); tree[t]=tree[2*t]+tree[2*t+1]; return ; } void pd(int t){ auto&x=tree[t/2],&y=tree[t]; y.tagf+=x.tagf; y.tagg+=x.tagg; y.sum+=x.tagf*y.num; y.minn+=x.tagg; return ; } void pushdown(int t){ pd(2*t),pd(2*t+1); tree[t].tagf=tree[t].tagg=0; return; } void changef(int t,int ll,int rr,int c){ if(ll>rr)return ; int l=tree[t].l,r=tree[t].r; if(ll<=l and r<=rr){ tree[t].sum+=tree[t].num*c; tree[t].tagf+=c; return ; } pushdown(t); int mid=l+r>>1; if(ll<=mid)changef(2*t,ll,rr,c); if(rr>mid)changef(2*t+1,ll,rr,c); tree[t]=tree[2*t]+tree[2*t+1]; return; } void changeg(int t,int ll,int rr,int c){ if(ll>rr)return ; int l=tree[t].l,r=tree[t].r; if(ll<=l and r<=rr){ tree[t].minn+=c; tree[t].tagg+=c; return ; } pushdown(t); int mid=l+r>>1; if(ll<=mid)changeg(2*t,ll,rr,c); if(rr>mid)changeg(2*t+1,ll,rr,c); tree[t]=tree[2*t]+tree[2*t+1]; return; } signed main(){ cin.tie(0)->sync_with_stdio(0); //freopen("1.in","r",stdin); cin>>n>>m; for(int i=1;i<n;++i){ cin>>u>>v; add(u,v); add(v,u); } for(int i=1;i<=n;++i)cin>>a[i],ia[a[i]]=i; //ia[1]=n;// b[1]=1; g[n-1]=1; int num=1; for(int i=n-1;i;--i){ ++num; b[a[i]]=1; for(int j=hd[a[i]];j;j=line[j].nxt){ int to=line[j].to; if(b[to])--num; } g[i-1]=num;//注意这里不是 i } b=0;num=0; for(int i=1;i<n;++i){ ++num;b[a[i]]=1; for(int j=hd[a[i]];j;j=line[j].nxt){ int to=line[j].to; if(b[to])--num; } f[i]=num; } --n;//操作只有 n-1 build(1,1,n); //cout<<tree[1].sum<<'\n'; while(m--){ cin>>u>>v>>x>>y; if(ia[u]>ia[v])swap(u,v); if(ia[x]>ia[y])swap(x,y); changef(1,ia[v],n,+1); changeg(1,1,ia[u]-1,+1);//-1 不要忘了 changef(1,ia[y],n,-1); changeg(1,1,ia[x]-1,-1);//同上 cout<<tree[1].sum+1<<'\n'; } return 0; }