1. 程式人生 > >luogu3250 網路 (整體二分+樹上差分+樹狀陣列)

luogu3250 網路 (整體二分+樹上差分+樹狀陣列)

首先整體二分,問題變成是否存在經過一個點的滿足條件的路徑

那麼我對於每個路徑(a,b,lca),在樹狀陣列的dfn[a]++,dfn[b]++,dfn[lca]--,dfn[fa[lca]--]

然後直接查那個點的子樹和就行了

  1 #include<bits/stdc++.h>
  2 #define CLR(a,x) memset(a,x,sizeof(a))
  3 #define MP make_pair
  4 using namespace std;
  5 typedef long long ll;
  6 typedef unsigned long
long ull; 7 typedef pair<int,int> pa; 8 const int maxn=2e5+10,maxm=4e5+10; 9 10 inline ll rd(){ 11 ll x=0;char c=getchar();int neg=1; 12 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 13 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 14 return
x*neg; 15 } 16 17 int N,M,eg[maxn*2][2],egh[maxn],ect; 18 int dfn[maxn][2],tot,fa[maxn][20],dep[maxn]; 19 int tr[maxn],ans[maxm],que[maxm]; 20 21 inline int lowbit(int x){return x&(-x);} 22 inline void add(int x,int y){ 23 for(;x&&x<=N;x+=lowbit(x)) tr[x]+=y; 24
} 25 inline int query(int x){ 26 int re=0;for(;x;x-=lowbit(x)) re+=tr[x];return re; 27 } 28 29 struct Node{ 30 int d,a,b,v,lca; 31 Node(int x=0,int y=0,int z=0,int l=0,int k=0){ 32 d=x,a=y,b=z,v=l,lca=k; 33 } 34 inline void cover(int x){ 35 add(dfn[a][0],d*x); 36 add(dfn[b][0],d*x); 37 add(dfn[lca][0],-d*x); 38 add(dfn[fa[lca][0]][0],-d*x); 39 } 40 }op[maxm],tmp[maxm]; 41 42 inline void adeg(int a,int b){ 43 eg[++ect][0]=b,eg[ect][1]=egh[a],egh[a]=ect; 44 } 45 46 inline void dfs(int x){ 47 for(int i=0;fa[x][i]&&fa[fa[x][i]][i];i++) 48 fa[x][i+1]=fa[fa[x][i]][i]; 49 dfn[x][0]=++tot; 50 for(int i=egh[x];i;i=eg[i][1]){ 51 int b=eg[i][0];if(b==fa[x][0]) continue; 52 dep[b]=dep[x]+1,fa[b][0]=x;dfs(b); 53 }dfn[x][1]=tot; 54 } 55 56 inline int getlca(int x,int y){ 57 if(dep[x]<dep[y]) swap(x,y); 58 for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){ 59 if(dep[fa[x][i]]>=dep[y]) 60 x=fa[x][i]; 61 } 62 if(x==y) return x; 63 for(int i=log2(dep[x]);i>=0;i--){ 64 if(fa[x][i]!=fa[y][i]) 65 x=fa[x][i],y=fa[y][i]; 66 }return fa[x][0]; 67 } 68 69 inline void solve(int l,int r,int vl,int vr){ 70 if(l>r||vl>vr) return; 71 int a=l-1,b=r+1,mid=vl+vr>>1; 72 int cnt=0; 73 74 for(int i=l;i<=r;i++){ 75 if(op[i].d){ 76 if(op[i].v>=mid) tmp[--b]=op[i],op[i].cover(1),cnt+=op[i].d; 77 else tmp[++a]=op[i]; 78 }else{ 79 int re=query(dfn[op[i].a][1])-query(dfn[op[i].a][0]-1); 80 if(cnt-re>=1) tmp[--b]=op[i],ans[op[i].b]=mid; 81 else tmp[++a]=op[i]; 82 } 83 } 84 85 for(int i=l;i<=r;i++){ 86 if(op[i].d&&op[i].v>=mid) op[i].cover(-1); 87 } 88 89 for(int i=l;i<=a;i++) op[i]=tmp[i]; 90 for(int i=r;i>=b;i--) op[i]=tmp[r-i+b]; 91 solve(l,a,vl,mid-1);solve(b,r,mid+1,vr); 92 } 93 94 int main(){ 95 // freopen("network4.in","r",stdin); 96 int i,j,k; 97 N=rd(),M=rd(); 98 for(i=1;i<N;i++){ 99 int a=rd(),b=rd(); 100 adeg(a,b);adeg(b,a); 101 } 102 dep[1]=1;dfs(1); 103 for(i=1,j=0;i<=M;i++){ 104 int o=rd(); 105 if(o==0){ 106 int a=rd(),b=rd(),c=rd(); 107 op[i]=Node(1,a,b,c,getlca(a,b)); 108 }else if(o==1){ 109 int t=rd(); 110 op[i]=Node(-1,op[t].a,op[t].b,op[t].v,op[t].lca); 111 }else{ 112 op[i]=Node(0,rd(),i,0,0); 113 que[++j]=i; 114 } 115 } 116 CLR(ans,-1); 117 solve(1,M,1,1e9); 118 for(i=1;i<=j;i++){ 119 printf("%d\n",ans[que[i]]); 120 } 121 return 0; 122 }