zoukankan      html  css  js  c++  java
  • BZOJ1103 [POI2007]大都市meg dfs序 线段树

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ1103


    题意概括

      一棵树上,一开始所有的边权值为1,我们要支持两种操作:

      1. 修改某一条边的权值为0

      2. 询问根节点到某一节点的路径权值和


    题解

      前置技能 - dfs序相关

      然后差不多你就会了。

      dfs序+线段树搞定了。


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int N=250000+5;
    struct Gragh{
        int cnt,x[N],y[N],nxt[N],fst[N];
        void set(){
            cnt=0;
            memset(fst,0,sizeof fst);
        }
        void add(int a,int b){
            x[++cnt]=a,y[cnt]=b;
            nxt[cnt]=fst[a],fst[a]=cnt;
        }
    }g;
    int n,m,fa[N],in[N],out[N],dis[N],time;
    char ch[3];
    struct SegTree{
        int v,add;
    }t[N*4];
    void dfs(int rt){
        in[rt]=++time;
        for (int i=g.fst[rt];i;i=g.nxt[i])
            dis[g.y[i]]=dis[rt]+1,dfs(g.y[i]);
        out[rt]=time;
    }
    void build(int rt,int le,int ri){
        t[rt].add=t[rt].v=0;
        if (le==ri)
            return;
        int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
        build(ls,le,mid);
        build(rs,mid+1,ri);
    }
    void pushdown(int rt){
        if (!t[rt].add)
            return;
        int ls=rt<<1,rs=ls|1,&v=t[rt].add;
        t[ls].add+=v,t[ls].v+=v;
        t[rs].add+=v,t[rs].v+=v;
        v=0;
    }
    void update(int rt,int le,int ri,int xle,int xri){
        if (ri<xle||le>xri)
            return;
        if (xle<=le&&ri<=xri){
            t[rt].add++,t[rt].v++;
            return;
        }
        pushdown(rt);
        int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
        update(ls,le,mid,xle,xri);
        update(rs,mid+1,ri,xle,xri);
    }
    int query(int rt,int le,int ri,int x){
        if (le==ri)
            return t[rt].v;
        pushdown(rt);
        int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
        if (x<=mid)
            return query(ls,le,mid,x);
        else
            return query(rs,mid+1,ri,x);
    }
    int main(){
        g.set();
        scanf("%d",&n);
        for (int i=1,a,b;i<n;i++){
            scanf("%d%d",&a,&b);
            if (a>b)
                swap(a,b);
            fa[b]=a,g.add(a,b);
        }
        time=dis[1]=0;
        dfs(1);
        build(1,1,n);
        scanf("%d",&m);
        m+=n-1;
        while (m--){
            int x,a,b;
            scanf("%s",ch);
            if (ch[0]=='W'){
                scanf("%d",&x);
                printf("%d
    ",dis[x]-query(1,1,n,in[x]));
            }
            else {
                scanf("%d%d",&a,&b);
                if (a>b)
                    swap(a,b);
                update(1,1,n,in[b],out[b]);
            }
        }
        return 0;
    }
  • 相关阅读:
    异步编程(二)----------------多线程
    异步编程(一)
    爬虫笔记(四)--基于bs4
    统计某学校考研录取信息
    爬虫笔记(三)爬取‘糗事百科’热图板块所有图
    Day1登录接口编写
    元祖
    列表
    常用函数
    字符串
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1103.html
Copyright © 2011-2022 走看看