zoukankan      html  css  js  c++  java
  • 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
    ",ans[que[i]]);
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    存储函数
    Laravel的请求声明周期
    哪只猴子可以当大王
    有多少苹果用来分赃
    SqlDataAdapter使用小结
    主键与外键
    SQL server 操作相关
    C# 窗体相关知识
    C#中winform DataGridView常用修改点
    maven 坐标获取方式
  • 原文地址:https://www.cnblogs.com/Ressed/p/10050630.html
Copyright © 2011-2022 走看看