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

    题目链接

    树剖题不用多说,一开始所有黑边的权值是-1,若有修改白边的操作,就把白边的值赋为100000。

    之后查询边权之和时,如果和大于1000000,就肯定存在白边,直接输出-1。

    //做法:树剖,一开始黑边边权全设为1,若有修改白边,设为100000
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+7;
    struct node{
        int nxt,to,val,from;
    }edge[maxn*4];
    int head[maxn],cnt;
    void add(int x,int y,int v){
        edge[++cnt].nxt=head[x];
        edge[cnt].from=x;
        edge[cnt].to=y;
        edge[cnt].val=v;
        head[x]=cnt;
    }
    int n,m;
    int x,y;
    int opt,num;
    int dep[maxn],fa[maxn],size[maxn],son[maxn],w[maxn];
    void dfs1(int x,int f){
        fa[x]=f;
        size[x]=1;
        dep[x]=dep[f]+1;
        int maxson=-1;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(v==fa[x]) continue;
            w[v]=edge[i].val;
            dfs1(v,x);
            size[x]+=size[v];
            if(size[v]>maxson){
                maxson=size[v];
                son[x]=v;
            }
        }
    }
    int id[maxn],top[maxn],va[maxn],Time;
    void dfs2(int x,int topf){
        top[x]=topf;
        id[x]=++Time;
        va[id[x]]=w[x];
        if(!son[x]) return;
        dfs2(son[x],topf);
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(v==fa[x]||v==son[x]) continue;
            dfs2(v,v);
        }
    }
    struct nod{
        int l,r;
        long long sum;
        int lazy;
    }tree[maxn*4];
    void build(int now,int l,int r){
        tree[now].l=l,tree[now].r=r,tree[now].lazy=-1;
        if(l==r){
            tree[now].sum=va[l];
            return;
        }
        int mid=(l+r)>>1;
        build(now<<1,l,mid);
        build(now<<1|1,mid+1,r);
        tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
    }
    void pushdown(int now){
        if(tree[now].lazy!=-1){
            tree[now<<1].sum=(tree[now<<1].r-tree[now<<1].l+1)*tree[now].lazy;
            tree[now<<1|1].sum=(tree[now<<1|1].r-tree[now<<1|1].r+1)*tree[now].lazy;
            tree[now<<1].lazy=tree[now].lazy;
            tree[now<<1|1].lazy=tree[now].lazy;
            tree[now].lazy=-1;
        }
    }
    void update(int now,int l,int r,int v){
        if(tree[now].l>=l&&tree[now].r<=r){
            tree[now].sum=(tree[now].r-tree[now].l+1)*v;
            tree[now].lazy=v;
            return;
        } 
        pushdown(now);
        int mid=(tree[now].l+tree[now].r)>>1;
        if(l<=mid) update(now<<1,l,r,v);
        if(r>mid) update(now<<1|1,l,r,v);
        tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
    }
    long long query(int now,int l,int r){
        if(tree[now].l>=l&&tree[now].r<=r) return tree[now].sum;
        pushdown(now);
        int mid=(tree[now].l+tree[now].r)>>1;
        long long val=0;
        if(l<=mid) val+=query(now<<1,l,r);
        if(r>mid) val+=query(now<<1|1,l,r);
        return val;
    }
    long long link(int x,int y){
        long long ans=0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans+=query(1,id[top[x]],id[x]);
            x=fa[top[x]];
        }
        if(dep[x]<dep[y]) swap(x,y);
        ans+=query(1,id[y]+1,id[x]);
        return ans;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            add(x,y,1);add(y,x,1);
        }
        scanf("%d",&m);
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n);
        for(int i=1;i<=m;i++){
            scanf("%d",&opt);
            if(opt==2){
                scanf("%d",&num);
                int s=edge[num*2].from;
                int t=edge[num*2].to;
                if(dep[s]>dep[t]) swap(s,t);
                update(1,id[t],id[t],1000000);
            } 
            else if(opt==1){
                scanf("%d",&num);
                int s=edge[num*2].from;
                int t=edge[num*2].to;
                if(dep[s]>dep[t]) swap(s,t);
                update(1,id[t],id[t],1);
            }
            else{
                scanf("%d%d",&x,&y);
                if(link(x,y)>=1000000) printf("-1
    ");
                else printf("%lld
    ",link(x,y));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ruby 二进制转十进制 Integer("0b101") = 5
    开始菜单和我的文档的我的图片及我的音乐变成 my pictrues 正常图标了
    ruby watir 莫名其妙的错误
    Excel SaveAS是去掉提示框
    apache && jboss安装
    ruby require include的区别
    ruby控制鼠标
    This error is raised because the column 'type' is reserved for storing the class in case of inheritance
    用正则表达式限制文本框只能输入数字,小数点,英文字母,汉字等各类代码
    ASP.NET 如何动态修改 Header 属性如添加 Meta 标签 keywords description!
  • 原文地址:https://www.cnblogs.com/LJB666/p/11432154.html
Copyright © 2011-2022 走看看