zoukankan      html  css  js  c++  java
  • bzoj 1103 : [POI2007]大都市meg (树链剖分+线段树)

    Description

      在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了。
    不过,她经常回忆起以前在乡间漫步的情景。昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双
    向的土路。从每个村庄都恰好有一条路径到达村庄1(即比特堡)。并且,对于每个村庄,它到比特堡的路径恰好
    只经过编号比它的编号小的村庄。另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇。在这个未开
    化的地方,从来没有过高架桥和地下铁道。随着时间的推移,越来越多的土路被改造成了公路。至今,Blue Mary
    还清晰地记得最后一条土路被改造为公路的情景。现在,这里已经没有土路了——所有的路都成为了公路,而昔日
    的村庄已经变成了一个大都市。 Blue Mary想起了在改造期间她送信的经历。她从比特堡出发,需要去某个村庄,
    并且在两次送信经历的间隔期间,有某些土路被改造成了公路.现在Blue Mary需要你的帮助:计算出每次送信她需
    要走过的土路数目。(对于公路,她可以骑摩托车;而对于土路,她就只好推车了。)

    Input

      第一行是一个数n(1 < = n < = 2 50000).以下n-1行,每行两个整数a,b(1 < =  a以下一行包含一个整数m
    (1 < = m < = 2 50000),表示Blue Mary曾经在改造期间送过m次信。以下n+m-1行,每行有两种格式的若干信息
    ,表示按时间先后发生过的n+m-1次事件:若这行为 A a b(a若这行为 W a, 则表示Blue Mary曾经从比特堡送信到
    村庄a。

    Output

      有m行,每行包含一个整数,表示对应的某次送信时经过的土路数目。

    Sample Input

    5
    1 2
    1 3
    1 4
    4 5
    4
    W 5
    A 1 4
    W 5
    A 4 5
    W 5
    W 2
    A 1 2
    A 1 3

    Sample Output

    2
    1
    0
    1

    HINT

     
    水题
     
    实现代码:
    #include<bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define mid int m = (l + r) >> 1;
    const int M = 5e5+10;
    int sum[M<<2],lazy[M<<2],son[M],siz[M],head[M],top[M],fa[M],dep[M],tid[M<<2],rk[M<<2];
    int u[M],v[M],cnt1,cnt,wt[M],n,m;
    struct node{
        int to,next,w;
    }e[M];
    
    void add(int u,int v){
        e[++cnt1].to=v;e[cnt1].next=head[u];head[u]=cnt1;
        e[++cnt1].to=u;e[cnt1].next=head[v];head[v]=cnt1;
    }
    void dfs1(int u,int faz,int deep){
        dep[u] = deep;
        siz[u] = 1;
        fa[u] = faz;
        for(int i = head[u];i ;i=e[i].next){
            int v = e[i].to;
            if(v != fa[u]){
                wt[v] = e[i].w;
                dfs1(v,u,deep+1);
                siz[u] += siz[v];
                if(son[u]==-1||siz[v]>siz[son[u]])
                    son[u] = v;
            }
        }
    }
    
    void dfs2(int u,int t){
        top[u] = t;
        tid[u] = cnt;
        //cout<<1<<endl;
        cnt++;
        if(son[u] == -1) return ;
        dfs2(son[u],t);
        for(int i = head[u];i;i=e[i].next){
            int v = e[i].to;
            if(v != son[u]&&v != fa[u])
                dfs2(v,v);
        }
    }
    
    void pushup(int rt){
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    
    void pushdown(int rt){
        if(lazy[rt]){
            sum[rt<<1] = sum[rt<<1|1] = lazy[rt] = 0;
            lazy[rt<<1] = lazy[rt<<1|1] = 1;
        }
    }
    
    void build(int l,int r,int rt){
        if(l == r){
            sum[rt] = 1;
            return ;
        }
        mid;
        build(lson); build(rson);
        pushup(rt);
    }
    
    void update(int L,int R,int l,int r,int rt){
        if(L <= l&&R >= r){
            sum[rt] = 0;
            lazy[rt] = 1;
            return ;
        }
        pushdown(rt);
        mid;
        if(L <= m) update(L,R,lson);
        if(R > m) update(L,R,rson);
        pushup(rt);
    }
    
    int query(int L,int R,int l,int r,int rt){
        if(L <= l&&R >= r){
            return sum[rt];
        }
        pushdown(rt);
        mid;
        int ret = 0;
        if(L <= m) ret += query(L,R,lson);
        if(R > m) ret += query(L,R,rson);
        return ret;
    }
    
    void update(int x,int y){
        int fx = top[x],fy = top[y];
        while(fx != fy){
            if(dep[fx] < dep[fy]) swap(x,y),swap(fx,fy);
            if(fx == 1) update(tid[fx]+1,tid[x],1,n,1);
            else update(tid[fx],tid[x],1,n,1);
            x = fa[fx]; fx = top[x];
        }
        if(x == y) return ;
        if(dep[x] > dep[y]) swap(x,y);
        update(tid[x]+1,tid[y],1,n,1);
        return ;
    }
    
    int solve(int x,int y){
        int ans = 0;
        int fx = top[x],fy = top[y];
        while(fx != fy){
            if(dep[fx] < dep[fy]) swap(x,y),swap(fx,fy);
            if(fx == 1) ans += query(tid[fx]+1,tid[x],1,n,1);
            else ans += query(tid[fx],tid[x],1,n,1);
            x = fa[fx]; fx = top[x];
        }
        if(x == y) return ans;
        if(dep[x] > dep[y]) swap(x,y);
        ans += query(tid[x]+1,tid[y],1,n,1);
        return ans;
    }
    
    int main()
    {
        int u,v,l,r,q,x;
        char op[100];
        scanf("%d",&n);
        memset(son,-1,sizeof(son));
        for(int i = 2;i <= n;i ++){
            scanf("%d%d",&u,&v);
            add(u,v);
        }
        dfs1(1,0,1); dfs2(1,0);
        build(1,n,1);
        scanf("%d",&q);
        q += n-1;
        while(q--){
            scanf("%s",op);
            if(op[0] == 'W'){
                scanf("%d",&x);
                printf("%d
    ",solve(x,1));
            }
            else {
                scanf("%d%d",&l,&r);
                update(l,r);
            }
        }
        return 0;
    }
  • 相关阅读:
    深度学习遥感影像(哨兵2A/B)超分辨率
    基于Google Earth Engine的全国地表温度反演
    蚂蚁森林的树木长得如何了?遥感云计算告诉你!!
    基于单分类器的高分辨率遥感影像道路提取
    基于google earth engine 云计算平台的全国水体变化研究
    超大影像栅格转矢量快速实现
    大规模深度学习多通道遥感图像样本增强
    大规模遥感影像匀光匀色的一些思考
    基于深度学习的珠海一号高光谱影像云检测
    全自动多源遥感影像大气校正方法
  • 原文地址:https://www.cnblogs.com/kls123/p/9910926.html
Copyright © 2011-2022 走看看