zoukankan      html  css  js  c++  java
  • CF165D Beard Graph

    这就是一个树剖裸题,但给的是边权。

    这题会板子的话,只需考虑如何来写线段树维护这道题维护的东西和边权化点权。

    我对于边权化点权是在两点连线之间建立一个点,把边

    权给它,节点数就会变为 2*n+1 ,而代表边的点编号都为边的编号加n。

    每次修改的时候把x改成x+n就是要修改边所对应的的编号。

    对于黑边,给它赋值为1,而白边赋值为0,修改就是单点修改,查询的话,查询区

    间和,再利用树剖LCA判断两点之间的距离是否是ans的2倍,若是,则全是黑边,

    若不是则输出-1。然后这题就做完了。

    AC代码

    #include<iostream>
    #include<cstdio>
    #define lson k<<1,l,mid
    #define rson k<<1|1,mid+1,r
    #define ls k<<1
    #define rs k<<1|1
    #define mid ((l+r)>>1)
    using namespace std;
    const int N=200005;
    int n,m,cnt,tot,ans;
    int head[N],id[N],top[N],fa[N],siz[N],son[N],dep[N],dfn[N];
    int tr[N<<2];
    bool flag;
    struct node{
        int to,nxt;
    }e[N<<1];
    inline int read(){
        int s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
        return s*w;
    }
    inline void add(int from,int to){
        e[++cnt]=(node){to,head[from]};
        head[from]=cnt;
    }
    void dfs1(int x,int f){
        dep[x]=dep[f]+1;fa[x]=f;siz[x]=1;
        int y;
        for(int i=head[x];i;i=e[i].nxt){
            y=e[i].to;
            if(y==f)continue;
            dfs1(y,x);
            siz[x]+=siz[y];
            if(siz[y]>siz[son[x]])son[x]=y;
        }
    }
    void dfs2(int x,int topf){
        top[x]=topf;id[x]=++tot;dfn[tot]=x;
        if(!son[x])return ;
        dfs2(son[x],topf);
        int y;
        for(int i=head[x];i;i=e[i].nxt){
            y=e[i].to;
            if(y==fa[x]||y==son[x])continue;
            dfs2(y,y);
        }
    }
    inline void update(int k){
        tr[k]=tr[ls]+tr[rs];
    }
    void build(int k,int l,int r){
        if(l==r){
            tr[k]=dfn[l]>n?1:0;
            return ;
        }
        build(lson);build(rson);
        update(k);
    }
    void change(int k,int l,int r,int x,int y){
        if(l==r&&x==l){
            tr[k]=y;
            return ;
        }
        if(x<=mid)change(lson,x,y);
        else change(rson,x,y);
        update(k);
    }
    int ask(int k,int l,int r,int x,int y){
        if(l==x&&y==r){
            return tr[k];
        }
        if(y<=mid)return ask(lson,x,y);
        else if(x>mid)return ask(rson,x,y);
        else return ask(lson,x,mid)+ask(rson,mid+1,y);
    }
    inline void qurey(int x,int y){
        ans=0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            ans+=ask(1,1,n*2-1,id[top[x]],id[x]);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        ans+=ask(1,1,n*2-1,id[x],id[y]);
    }
    inline int LCA(int x, int y) {
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])
                swap(x,y);
            x=fa[top[x]];
        }
        return dep[x]<dep[y]?x:y;
    }
    inline void check(int x,int y){
        int dis=dep[x]+dep[y]-2*dep[LCA(x,y)];
        if(dis!=ans*2)flag=1;
    }
    int main(){
        n=read();
        int x,y;
        for(int i=1;i<n;++i){
            x=read();y=read();
            add(x,i+n);add(i+n,x);
            add(i+n,y);add(y,i+n);
        }
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n*2-1);
        m=read();
        int opt;
        while(m--){
            opt=read();x=read();
            if(opt==1)change(1,1,n*2-1,id[x+n],1);
            else if(opt==2)change(1,1,n*2-1,id[x+n],0);
            else {
                flag=0;
                y=read();
                qurey(x,y);
                check(x,y);
                if(flag)printf("-1
    ");
                else printf("%d
    ",ans);
            }
        }
    }
  • 相关阅读:
    php 函数strpos()
    uploadfy api中文文档
    thinkphp + 美图秀秀api 实现图片裁切上传,带数据库
    mysql 操作用户权限
    window.location 小结)
    turn.js 图书翻页效果
    thinkphp 内置标签volist 控制换行
    js 数据类型转换
    quartz 2.2.1
    Mysql测试链接
  • 原文地址:https://www.cnblogs.com/sanjinliushi/p/11741703.html
Copyright © 2011-2022 走看看