• HDU3966-Aragorn's Story-树链剖分-点权


    很模板的树链剖分题

    注意什么时候用线段树上的标号,什么时候用点的标号。

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    
    using namespace std;
    const int maxn = 50005;
    int val_pre[maxn],val[maxn],siz[maxn],son[maxn],id[maxn],fa[maxn],top[maxn],dep[maxn];
    int topw;
    int M,N,P;
    
    vector<int> G[maxn];
    
    void dfs_1(int u,int f,int d)
    {
        siz[u] = 1;
        fa[u]  = f;
        dep[u] = d;
        son[u] = 0;
        for(int i=0;i<G[u].size();i++)
        {
            int v = G[u][i];
            if(v == f) continue;
            dfs_1(v,u,d+1);
            siz[u] += siz[v];
            if(siz[son[u]] < siz[v])
                son[u] = v;
        }
    }
    
    void dfs_2(int u,int tp)
    {
        top[u] = tp;
        id[u] = ++topw;
        if(son[u]) dfs_2(son[u],tp);
        for(int i=0;i<G[u].size();i++)
        {
            int v = G[u][i];
            if(v == fa[u]|| v==son[u]) continue;
            dfs_2(v,v);
        }
    }
    
    void debug()
    {
        for(int i=1;i<=N;i++)
        {
            printf("%d siz:%d son:%d dep:%d fa:%d ",i,siz[i],son[i],dep[i],fa[i]);
            printf("top:%d id:%d
    ",top[i],id[i]);
        }
    }
    
    ////////////////////////////////////////
    //Segment Tree
    
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    int add[maxn<<2];
    void push_down(int rt)
    {
        if(add[rt])
        {
            add[rt<<1] += add[rt];
            add[rt<<1|1] += add[rt];
            add[rt] = 0;
        }
    }
    
    void build(int l,int r,int rt)
    {
        add[rt] = 0;
        if(l == r)
        {
            add[rt] = val[r];
            return ;
        }
        int m = (l+r)>>1;
        build(lson);
        build(rson);
    }
    
    void update(int L,int R,int c,int l,int r,int rt)
    {
        if(L<=l && R>= r)
        {
            add[rt] += c;
            return ;
        }
        push_down(rt);
        int m = (l+r)>>1;
        if(L<=m) update(L,R,c,lson);
        if(R> m) update(L,R,c,rson);
    }
    
    int query(int x,int l,int r,int rt)
    {
        if(l == r)
        {
            return add[rt];
        }
        push_down(rt);
        int m = (l+r)>>1;
        if(x <= m) query(x,lson);
        else       query(x,rson);
    }
    
    void change(int u,int v,int add)
    {
        int fu = top[u],fv = top[v];
        while(fu != fv)
        {
            //printf("fu:%d u:%d v:%d fv:%d 
    ",fu,u,v,fv);
            if(dep[fu] < dep[fv])
            {
                swap(u,v);swap(fu,fv);
            }
            update(id[fu],id[u],add,1,topw,1);
            u = fa[fu];
            fu = top[u];
        }
        if(u == v)
        {
            update(id[u],id[v],add,1,topw,1);
            return;
        }
        else{
            if(dep[u] > dep[v]) swap(u,v);
            update(id[u],id[v],add,1,topw,1);
            return ;
        }
    }
    
    int main()
    {
        //freopen("input.in","r",stdin);
        while(~scanf("%d%d%d",&N,&M,&P))
        {
            for(int i=1;i<=N;i++) scanf("%d",&val_pre[i]);
            for(int i=1,a,b;i<=M;i++)
            {
                scanf("%d%d",&a,&b);
                G[a].push_back(b);
                G[b].push_back(a);
            }
            topw = 0;
            dfs_1(1,0,1);
            dfs_2(1,1);
            for(int i=1;i<=N;i++)
            {
                val[id[i]] = val_pre[i];
            }
            build(1,topw,1);
            //debug();
    
            char op[10];
            int a,b,c;
    
            for(int i=0;i<P;i++)
            {
                scanf("%s",op);
                if(op[0] == 'I')
                {
                    scanf("%d%d%d",&a,&b,&c);
                    change(a,b,c);
                }
                else if(op[0] == 'D')
                {
                    scanf("%d%d%d",&a,&b,&c);
                    change(a,b,-c);
                }
                else if(op[0] == 'Q')
                {
                    scanf("%d",&a);
                    int ans = query(id[a],1,topw,1);
                    printf("%d
    ",ans);
                }
            }
            for(int i=0;i<maxn;i++) G[i].clear();
        }
    }
  • 相关阅读:
    Silverlight 2中实现文件上传和电子邮件发送
    Silverlight结合Web Service进行文件上传
    silverlight DataGrid 内嵌ComboBox 实现加载和保存
    silverlight 使用IValueConverter 转换
    检测场所条件查询
    代码中的坏味道
    Prism初研究之Bootstrapper
    Prism初研究之简介
    编写可读代码的艺术
    ffmpeg怎么样处理网络流
  • 原文地址:https://www.cnblogs.com/helica/p/5670375.html
Copyright © 2020-2023  润新知