• [BZOJ]1103: [POI2007]大都市meg


    题目大意:一棵n个点的树,边权均为1,两种操作,一种把一条边边权改为0,另一种查询一个点到根的路径长度。(n<=250,000)

    思路:预处理出一开始各个点的答案,每次修改操作把子树内的所有答案减1,求出dfs序后用线段树维护即可,复杂度O(nlogn)。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        int x;char c;
        while((c=getchar())<'0'||c>'9');
        for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
        return x;
    }
    #define MN 250000
    #define N 262144
    struct edge{int nx,t;}e[MN*2+5];
    int h[MN+5],en,l[MN+5],r[MN+5],cnt,d[MN+5],t[N*2+5];
    inline void ins(int x,int y)
    {
        e[++en]=(edge){h[x],y};h[x]=en;
        e[++en]=(edge){h[y],x};h[y]=en;
    }
    void dfs(int x,int fa)
    {
        l[x]=++cnt;
        for(int i=h[x];i;i=e[i].nx)if(e[i].t!=fa)d[e[i].t]=d[x]+1,dfs(e[i].t,x);
        r[x]=cnt;
    }
    void dec(int l,int r)
    {
        for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
        {
            if(~l&1)--t[l+1];
            if( r&1)--t[r-1];
        }
    }
    int query(int x){int r=d[x];for(x=l[x]+N;x;x>>=1)r+=t[x];return r;}
    int main()
    {
        int n=read(),i,x;char s[5];
        for(i=1;i<n;++i)ins(read(),read());
        dfs(1,0);
        for(i=read()+n-1;i--;)
        {
            scanf("%s",s);
            if(s[0]=='W')printf("%d
    ",query(read()));
            else x=max(read(),read()),dec(l[x],r[x]);
        }
    }
  • 相关阅读:
    Maven导入com.google.common.collect jar包
    poj 2192 Zipper
    poj 3278 Catch That Cow
    poj 2488 A Knight's Journey
    poj 3982 序列
    poj 2109 Power of Cryptography
    poj 3258 3273
    java中大数的一些基本运算
    hdu 1715 大菲波数
    最小生成树模板
  • 原文地址:https://www.cnblogs.com/ditoly/p/BZOJ1103.html
Copyright © 2020-2023  润新知