未影响的最大值??
最值不能差分之类,难处理
二分答案!看是否覆盖所有大于mid路径!可以计数!树状数组维护dfn序,树上差分
多组询问?整体二分!
#include<bits/stdc++.h> #define reg register int #define il inline #define fi first #define se second #define mk(a,b) make_pair(a,b) #define numb (ch^'0') using namespace std; typedef long long ll; template<class T>il void rd(T &x){ char ch;x=0;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');} template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');} template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar(' ');} namespace Miracle{ const int N=1e5+5; const int M=2e5+5; const int inf=1e9; int n,m; struct node{ int nxt,to; }e[2*N]; int hd[N],cnt; void add(int x,int y){ e[++cnt].nxt=hd[x]; e[cnt].to=y; hd[x]=cnt; } int dep[N],fa[N][18]; int dfn[N],dfn2[N],fdfn[N]; int df; void dfs(int x,int d){ dep[x]=d; dfn[x]=++df;fdfn[df]=x; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(y==fa[x][0]) continue; fa[y][0]=x; dfs(y,d+1); } dfn2[x]=df; } int lca(int x,int y){ if(dep[x]<dep[y]) swap(x,y); for(reg j=17;j>=0;--j){ if(dep[fa[x][j]]>=dep[y]) x=fa[x][j]; } if(x==y) return x; for(reg j=17;j>=0;--j){ if(fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j]; } return fa[x][0]; } struct po{ int x,y,anc,val; }p[M]; struct event{//typ=1:add -1:dele 2:query int typ; int id,pos; }q[M],le[M],ri[M]; int tot; int ans[N]; int f[N]; void upda(int x,int c){ if(!x) return; for(;x<=n;x+=x&(-x)) f[x]+=c; } int query(int x){ int ret=0; for(;x;x-=x&(-x)) ret+=f[x];return ret; } void divi(int l,int r,int L,int R){ // cout<<" divi "<<l<<" and "<<r<<" : "<<L<<" && "<<R<<endl; if(l>r) return; if(L==R){ for(reg i=l;i<=r;++i){ if(q[i].typ==2){ if(L==0) ans[q[i].id]=-1; else ans[q[i].id]=L; } } return ; } int mid=(L+R)>>1; int pl=0,pr=0; int cnt=0; for(reg i=l;i<=r;++i){ // cout<<" i "<<i<<" typ "<<q[i].typ<<endl; if(q[i].typ==2){//query int now=query(dfn2[q[i].pos])-query(dfn[q[i].pos]-1); if(now<cnt){ ri[++pr]=q[i]; }else le[++pl]=q[i]; }else{ if(p[q[i].id].val>mid){ int lp=q[i].typ; cnt+=lp; upda(dfn[p[q[i].id].x],lp); upda(dfn[p[q[i].id].y],lp); upda(dfn[p[q[i].id].anc],-lp); upda(dfn[fa[p[q[i].id].anc][0]],-lp); ri[++pr]=q[i]; }else{ le[++pl]=q[i]; } } } for(reg i=l;i<=r;++i){ if(q[i].typ==2){//query continue; }else{ if(p[q[i].id].val>mid){ int lp=q[i].typ; upda(dfn[p[q[i].id].x],-lp); upda(dfn[p[q[i].id].y],-lp); upda(dfn[p[q[i].id].anc],lp); upda(dfn[fa[p[q[i].id].anc][0]],lp); } } } for(reg i=1;i<=pl;++i){ q[i+l-1]=le[i]; } for(reg i=1;i<=pr;++i){ q[l+pl-1+i]=ri[i]; } divi(l,l+pl-1,L,mid); divi(l+pl,r,mid+1,R); } int main(){ rd(n);rd(m); int x,y; for(reg i=1;i<n;++i) { rd(x);rd(y);add(x,y);add(y,x); } dfs(1,1); for(reg j=1;j<=17;++j){ for(reg i=1;i<=n;++i){ fa[i][j]=fa[fa[i][j-1]][j-1]; } } for(reg i=1;i<=m;++i){ rd(q[i].typ); if(q[i].typ==0){ q[i].typ=1; rd(p[i].x);rd(p[i].y);rd(p[i].val); p[i].anc=lca(p[i].x,p[i].y); q[i].id=i; } else if(q[i].typ==1){ q[i].typ=-1; rd(x);q[i].id=x; }else{ ++tot;q[i].id=tot; rd(q[i].pos); } } divi(1,m,0,inf); for(reg i=1;i<=tot;++i){ printf("%d ",ans[i]); } return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2019/3/22 17:15:06 */
最优化有时难以直接考虑,二分是一个不错的转化为判定问题,有时还可以转化为计数。