题解:P14380 【MX-S9-T3】「LAOI-16」天外来物
题目要求不同的
考虑这样的极小区间满足什么性质。可以发现,
所以,我们用
现在,一个
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+7;
int n,q,dfn[N],sz[N],tot,pre[N],suf[N];ll ans[N];
vector<pair<int,int>> Q[N];
vector<int> G[N],son[N],del[N];
inline void dfs(int u,int fa){
dfn[u]=++tot,sz[u]=1;
for(int &v:G[u]){
if(v==fa)continue;
dfs(v,u);
sz[u]+=sz[v],son[u].emplace_back(v);
}
}
#define mid ((l+r)>>1)
#define ls (rt<<1)
#define rs (rt<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
struct seg_min{
int tr[N<<2];
seg_min(){memset(tr,0x3f,sizeof(tr));}
inline void pushup(int rt){tr[rt]=min(tr[ls],tr[rs]);}
inline void add(int rt,int l,int r,int p,int val){
if(l==r){tr[rt]=val;return ;}
if(p<=mid)add(lson,p,val);
else add(rson,p,val);
pushup(rt);
}
inline int ask(int rt,int l,int r,int L,int R){
if(L>R)return 2e9;
if(L<=l&&r<=R)return tr[rt];
if(R<=mid)return ask(lson,L,R);
else if(L>mid)return ask(rson,L,R);
else return min(ask(lson,L,R),ask(rson,L,R));
}
} trmin;
struct seg_max{
int tr[N<<2];
inline void pushup(int rt){tr[rt]=max(tr[ls],tr[rs]);}
inline void add(int rt,int l,int r,int p,int val){
if(l==r){tr[rt]=val;return ;}
if(p<=mid)add(lson,p,val);
else add(rson,p,val);
pushup(rt);
}
inline int ask(int rt,int l,int r,int L,int R){
if(L>R)return 0;
if(L<=l&&r<=R)return tr[rt];
if(R<=mid)return ask(lson,L,R);
else if(L>mid)return ask(rson,L,R);
else return max(ask(lson,L,R),ask(rson,L,R));
}
} trmax;
struct seg_ask{
struct node{int num;ll cnt,tag;}tr[N<<4];
inline void update(int rt,ll val){tr[rt].cnt+=1ll*tr[rt].num*val,tr[rt].tag+=val;}
inline void pushdown(int rt){
if(!tr[rt].tag)return ;
update(ls,tr[rt].tag),update(rs,tr[rt].tag);
tr[rt].tag=0;
}
inline void pushup(int rt){tr[rt].num=tr[ls].num+tr[rs].num,tr[rt].cnt=tr[ls].cnt+tr[rs].cnt;}
inline void change(int rt,int l,int r,int p,int val){
if(l==r){tr[rt].num=val;return ;}
pushdown(rt);
if(p<=mid)change(lson,p,val);
else change(rson,p,val);
pushup(rt);
}
inline void add(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){update(rt,1);return ;}
pushdown(rt);
if(L<=mid)add(lson,L,R);
if(R>mid)add(rson,L,R);
pushup(rt);
}
inline ll ask(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R)return tr[rt].cnt;
pushdown(rt);
if(R<=mid)return ask(lson,L,R);
else if(L>mid)return ask(rson,L,R);
else return ask(lson,L,R)+ask(rson,L,R);
}
} trask;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>q;
for(int i=1,u,v;i<n;++i){
cin>>u>>v,G[u].emplace_back(v),G[v].emplace_back(u);
}dfs(1,0);
for(int i=1,maxn,sec,val;i<=n;++i){
trmax.add(1,1,n,dfn[i],i);
maxn=0,sec=0;
for(int &v:son[i]){
val=trmax.ask(1,1,n,dfn[v],dfn[v]+sz[v]-1);
if(val>maxn)sec=maxn,maxn=val;
else if(val>=sec)sec=val;
}
val=max(trmax.ask(1,1,n,1,dfn[i]-1),trmax.ask(1,1,n,dfn[i]+sz[i],n));
if(val>=maxn)sec=maxn,maxn=val;
else if(val>=sec)sec=val;
pre[i]=sec+1;
}
for(int i=n,minn,sec,val;i>=1;--i){
trmin.add(1,1,n,dfn[i],i);
minn=n+1,sec=n+1;
for(int &v:son[i]){
val=trmin.ask(1,1,n,dfn[v],dfn[v]+sz[v]-1);
if(val<minn)sec=minn,minn=val;
else if(val<sec)sec=val;
}
val=min(trmin.ask(1,1,n,1,dfn[i]-1),trmin.ask(1,1,n,dfn[i]+sz[i],n));
if(val<minn)sec=minn,minn=val;
else if(val<sec)sec=val;
suf[i]=sec-1;del[sec].emplace_back(i);
}
for(int i=1,l,r;i<=q;i++) cin>>l>>r,Q[r].emplace_back(l,i);
for(int i=1;i<=n;i++){
for(int &l:del[i])trask.change(1,1,n,l,0);
trask.change(1,1,n,i,1);trask.add(1,1,n,pre[i],i);
for(pair<int,int> &j:Q[i]) ans[j.second]=trask.ask(1,1,n,j.first,i);
}
for(int i=1;i<=q;i++)cout<<ans[i]<<'\n';
return 0;
}