• [HNOI2016]网络


     [HNOI2016]网络 

    未影响的最大值??

    最值不能差分之类,难处理

    二分答案!看是否覆盖所有大于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
    */

    最优化有时难以直接考虑,二分是一个不错的转化为判定问题,有时还可以转化为计数

  • 相关阅读:
    mysql的安装、启动和基础配置 —— windows版本
    Navicat安装及简单使用
    期货黄金与现货黄金比较
    android 网络编程--socket tcp/ip udp http之间的关系
    socket、tcp、udp、http 的认识及区别
    Android数据传递的五种方法汇总
    android 应用程序Activity之间数据传递与共享的几种途径
    Android数据存储的五种方法汇总
    Android终端与服务器数据传输解决方案
    转载 解决Android与服务器交互大容量数据问题
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10580390.html
Copyright © 2020-2023  润新知