zoukankan      html  css  js  c++  java
  • [BZOJ4538]网络

    本来想用树剖艹,然而并不会卡常数这种神奇的技能,,,于是还是乖乖写正解吧QAQ

    我们可以把一个询问转化为二分判定性问题

    二分答案$K$,若所有权值大于$K$的路径都经过询问点$x$,则答案比$K$小,否则答案比$K$大

    对于多组询问,外层再套一个整体二分就行了

    至于判断有几条路径经过点$x$,对于一条路径$(u,v)$我们把$u$和$v$置为$1$,$lca(u,v)$和$lca(u,v)$的父亲置为$-1$,这样经过一个节点$x$的路径条数就是以其为根的子树的标记和,,,

    由于子树区间求和有关,于是可以用dfs序维护

    然后可以$O(1)$求lca,即通过欧拉回路把lca转化为rmq问题

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define fir first
      4 #define sec second
      5 #define mp make_pair
      6 #define inf 0x3f3f3f3f
      7 #define maxn 100005
      8 #define maxm 200005
      9 pair<int,int>rng[maxn];
     10 struct node{
     11     int op,id,x,ans;
     12     bool operator<(const node &t)const{ return id<t.id; }
     13 }q[maxm],tmp[maxm];
     14 int cnt,v[maxn<<1],next[maxn<<1],first[maxn];
     15 int ss,ST[maxn<<2][20],log_2[maxn<<1],vis[maxn],dep[maxn];
     16 int n,m,A[maxm],B[maxm],C[maxm],dfn,BIT[maxn],fa[maxn];
     17 int read(){
     18     int ttt=0; char ch=0;
     19     while(ch<'0'||ch>'9')ch=getchar();
     20     while(ch>='0'&&ch<='9')ttt=ttt*10+ch-'0',ch=getchar();
     21     return ttt;
     22 }
     23 void add(int st,int end){
     24     v[++cnt]=end;
     25     next[cnt]=first[st];
     26     first[st]=cnt;
     27 }
     28 void dfs(int x){
     29     rng[x].fir=++dfn;
     30     ST[++ss][0]=x;
     31     if(!vis[x])vis[x]=ss;
     32     for(int e=first[x];e;e=next[e])
     33         if(v[e]!=fa[x]){
     34             fa[v[e]]=x,dep[v[e]]=dep[x]+1;
     35             dfs(v[e]);
     36             ST[++ss][0]=x;
     37         }
     38     rng[x].sec=dfn;
     39 }
     40 int Min(int x,int y){
     41     return dep[x]<dep[y]?x:y;
     42 }
     43 void build_ST(){
     44     log_2[1]=0;
     45     for(int i=2;i<=ss;i++)
     46         log_2[i]=log_2[i>>1]+1;
     47     for(int j=1;j<=log_2[ss];j++)
     48         for(int i=1;i<=ss;i++)
     49             ST[i][j]=Min(ST[i][j-1],ST[i+(1<<(j-1))][j-1]);
     50 }
     51 void update(int pos,int x){
     52     for(int i=pos;i<=n;i+=i&-i)
     53         BIT[i]+=x;
     54 }
     55 int query_ST(int x,int y){
     56     x=vis[x],y=vis[y];
     57     if(x>y)swap(x,y);
     58     int len=log_2[y-x+1];
     59     return Min(ST[x][len],ST[y-(1<<len)+1][len]);
     60 }
     61 //update操作传参biubiu
     62 void update_op(int x,int y,int op){
     63     int lca=query_ST(x,y);
     64     update(rng[x].fir,op),update(rng[y].fir,op);
     65     update(rng[lca].fir,-op);
     66     if(fa[lca])update(rng[fa[lca]].fir,-op);//
     67 }
     68 int query(int pos){
     69     int sum=0;
     70     for(int i=pos;i;i-=i&-i)sum+=BIT[i];
     71     return sum;
     72 }
     73 int query_op(int x){
     74     return query(rng[x].sec)-query(rng[x].fir-1);
     75 }
     76 void erfn(int L,int R,int l,int r){
     77     if(L>R)return;//
     78     int mid=(l+r)>>1;
     79     if(l==r){
     80         for(int i=L;i<=R;i++)
     81             if(q[i].op==2)q[i].ans=mid;
     82         return;
     83     }
     84     int qq=L-1,tt=0,num=0;
     85     for(int i=L;i<=R;i++){
     86         if(q[i].op==2){
     87             if(query_op(q[i].x)==num)q[++qq]=q[i];
     88             else tmp[++tt]=q[i];
     89         }
     90         else{
     91             int op=q[i].op?-1:1;
     92             if(C[q[i].x]<=mid)q[++qq]=q[i];
     93             else{
     94                 tmp[++tt]=q[i],num+=op;
     95                 update_op(A[q[i].x],B[q[i].x],op);
     96             }
     97         }
     98     }
     99     for(int i=1;i<=tt;i++)
    100         if(tmp[i].op!=2){
    101             int op=tmp[i].op?1:-1;
    102             update_op(A[tmp[i].x],B[tmp[i].x],op);
    103         }
    104     for(int i=1;i<=tt;i++)q[qq+i]=tmp[i];
    105     erfn(L,qq,l,mid);
    106     erfn(qq+1,qq+tt,mid+1,r);
    107 }
    108 int main(){
    109     n=read(),m=read();
    110     int a,b;
    111     for(int i=1;i<n;i++){
    112         a=read(),b=read();
    113         add(a,b),add(b,a);
    114     }
    115     dfs(1);
    116     build_ST();
    117     int r=0;
    118     for(int i=1;i<=m;i++){
    119         q[i].op=read();
    120         q[i].id=i;
    121         if(q[i].op==0){
    122             A[i]=read(),B[i]=read(),C[i]=read();
    123             q[i].x=i;
    124             r=max(r,C[i]);
    125         }
    126         else q[i].x=read();
    127     }
    128     erfn(1,m,-1,r);//
    129     sort(q+1,q+1+m);
    130     for(int i=1;i<=m;i++)
    131         if(q[i].op==2)printf("%d
    ",q[i].ans);
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    进入Docker 报错
    Oauth一直无限重定向
    jquery.click() not working in iOS
    IOS 系统 form 表单提交的问题;一直当前页面刷新
    Word 搜索功能显示bug
    百度脑图bug
    微信分享链接添加参数后缩略图不显示如何解决?
    微信分享到朋友圈 QQ空间 代码实现
    文献复现 | The support of human genetic evidence for approved drug indications
    生物医药领域 | 知名投资人 | VC | PE | IBD | 公募 | 私募
  • 原文地址:https://www.cnblogs.com/Ngshily/p/5413933.html
Copyright © 2011-2022 走看看