加入删除都有
线段树分治?二进制分组?整体二分?
线段树分治时间轴建树,询问修改各(nlog)个
但是咋处理询问!?是不经过的最大值
瞄了眼之前的代码 又作弊!
竟然是整体二分
把大于(mid)的加入,若经过的=总共加入的->([l,mid]),否则到右半段
树状数组即可
时间复杂度(O(nlog^2n))
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
const int N=1e5+4;
struct Ques{int u,v,w;}Q[N<<1];
struct ques{int u,v,w,t,id;}q[N<<1],q1[N<<1],q2[N<<1];
int dep[N],siz[N],fa[N],son[N],st[N],ed[N],top[N],tim=0;
vector<int>e[N];
int n,m,t[N],ans[N<<1],cnt=0,num=0;
void dfs_1(int x){
dep[x]=dep[fa[x]]+1;
siz[x]=1;
for(auto v:e[x]){
if(v==fa[x])continue;
fa[v]=x;
dfs_1(v);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]])son[x]=v;
}
}
void dfs_2(int x,int tp){
top[x]=tp;
st[x]=++tim;
if(son[x])dfs_2(son[x],tp);
for(auto v:e[x]){
if(v==fa[x]||v==son[x])continue;
dfs_2(v,v);
}
ed[x]=tim;
}
inline int getlca(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])u^=v^=u^=v;
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
inline void add(int x,int v){
if(!x)return;
for(;x<=n;x+=x&-x)t[x]+=v;
}
inline int ask(int x){
int ret=0;
for(;x;x-=x&-x)ret+=t[x];
return ret;
}
void solve(int al,int ar,int ql,int qr){
if(ql>qr)return;
if(al==ar){
if(!ar)ar=-1;
for(int i=ql;i<=qr;i++)
if(!q[i].id)ans[q[i].w]=ar;
return;
}
int mid=al+ar>>1,cn1=0,cn2=0;
for(int i=ql,lca,lei=0,c;i<=qr;i++){
if(!q[i].id){
if(ask(ed[q[i].u])-ask(st[q[i].u]-1)==lei)q1[++cn1]=q[i];
else q2[++cn2]=q[i];
}
else if(q[i].w>mid){
lca=getlca(q[i].u,q[i].v);
c=q[i].id;
lei+=c;
add(st[q[i].u],c);add(st[q[i].v],c);
add(st[lca],-c);add(st[fa[lca]],-c);
q2[++cn2]=q[i];
}
else q1[++cn1]=q[i];
}
for(int i=ql,lca,c;i<=qr;i++)
if(q[i].id&&q[i].w>mid){
lca=getlca(q[i].u,q[i].v);
c=q[i].id;
add(st[q[i].u],-c);add(st[q[i].v],-c);
add(st[lca],c);add(st[fa[lca]],c);
}
for(int i=1;i<=cn1;i++)q[ql+i-1]=q1[i];
for(int i=1;i<=cn2;i++)q[ql+cn1+i-1]=q2[i];
solve(al,mid,ql,ql+cn1-1);solve(mid+1,ar,ql+cn1,qr);
}
int main(){
n=read();m=read();
for(int i=1,u,v;i<n;i++){
u=read();v=read();
e[u].push_back(v);e[v].push_back(u);
}
dfs_1(1);
dfs_2(1,1);
for(int i=1,op,u,v,w;i<=m;i++){
op=read();u=read();
if(op==1)q[++cnt]=(ques){Q[u].u,Q[u].v,Q[u].w,i,-1};
else if(op==2)q[++cnt]=(ques){u,0,++num,i,0};
else{
v=read();w=read();
q[++cnt]=(ques){u,v,w,i,1};
Q[i]=(Ques){u,v,w};
}
}
solve(0,1e9,1,cnt);
for(int i=1;i<=num;i++)cout<<ans[i]<<"
";
return (0-0);
}