zoukankan      html  css  js  c++  java
  • 洛谷 P3038 [USACO11DEC]牧草种植Grass Planting(树链剖分)

    题解:仍然是无脑树剖,要注意一下边权,然而这种没有初始边权的题目其实和点权也没什么区别了

    代码如下:

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define lson root<<1
    #define rson root<<1|1
    using namespace std;
    
    struct node
    {
        int lazy,sum,l,r;
    } tr[400040];
    int deep[100010],fa[100010],son[100010],size[100010],id[100010],top[100010],cnt;
    vector<int> g[100010];
    
    void push_up(int root)
    {
        tr[root].sum=tr[lson].sum+tr[rson].sum;
    }
    
    void push_down(int root)
    {
        int mid=(tr[root].l+tr[root].r)>>1;
        tr[lson].sum+=tr[root].lazy*(mid-tr[root].l+1);
        tr[lson].lazy+=tr[root].lazy;
        tr[rson].sum+=tr[root].lazy*(tr[root].r-mid);
        tr[rson].lazy+=tr[root].lazy;
        tr[root].lazy=0;
    }
    
    void build(int root,int l,int r)
    {
        if(l==r)
        {
            tr[root].l=l;
            tr[root].r=r;
            tr[root].sum=0;
            return ;
        }
        tr[root].l=l;
        tr[root].r=r;
        int mid=(l+r)>>1;
        build(lson,l,mid);
        build(rson,mid+1,r);
        push_up(root);
    }
    
    void update(int root,int l,int r,int val)
    {
        if(l>r)
        {
            return;
        }
        if(l==tr[root].l&&tr[root].r==r)
        {
            tr[root].sum+=val*(tr[root].r-tr[root].l+1);
            tr[root].lazy+=val;
            return ;
        }
        if(tr[root].lazy)
        {
            push_down(root);
        }
        int mid=(tr[root].l+tr[root].r)>>1;
        if(l>mid)
        {
            update(rson,l,r,val);
        }
        else
        {
            if(r<=mid)
            {
                update(lson,l,r,val);
            }
            else
            {
                update(lson,l,mid,val);
                update(rson,mid+1,r,val);
            }
        }
        push_up(root);
    }
    
    int query(int root,int l,int r)
    {
        if(l>r)
        {
            return 0;
        }
        if(l==tr[root].l&&r==tr[root].r)
        {
            return tr[root].sum;
        }
        if(tr[root].lazy)
        {
            push_down(root);
        }
        int mid=(tr[root].l+tr[root].r)>>1;
        if(l>mid)
        {
            return query(rson,l,r);
        }
        else
        {
            if(r<=mid)
            {
                return query(lson,l,r);
            }
        }
        return query(lson,l,mid)+query(rson,mid+1,r);
    }
    
    void dfs1(int now,int f,int dep)
    {
        deep[now]=dep;
        fa[now]=f;
        size[now]=1;
        int maxson=-1;
        for(int i=0; i<g[now].size(); i++)
        {
            if(g[now][i]==f)
            {
                continue;
            }
            dfs1(g[now][i],now,dep+1);
            size[now]+=size[g[now][i]];
            if(size[g[now][i]]>maxson)
            {
                son[now]=g[now][i];
                maxson=size[g[now][i]];
            }
        }
    }
    
    void dfs2(int now,int topf)
    {
        id[now]=++cnt;
        top[now]=topf;
        if(!son[now])
        {
            return ;
        }
        dfs2(son[now],topf);
        for(int i=0; i<g[now].size(); i++)
        {
            if(fa[now]==g[now][i]||son[now]==g[now][i])
            {
                continue;
            }
            dfs2(g[now][i],g[now][i]);
        }
    }
    
    void path_update(int x,int y,int val)
    {
        while(top[x]!=top[y])
        {
            if(deep[top[x]]<deep[top[y]])
            {
                swap(x,y);
            }
            update(1,id[top[x]],id[x],val);
            x=fa[top[x]];
        }
        if(deep[x]>deep[y])
        {
            swap(x,y);
        }
        update(1,id[x]+1,id[y],val);
    }
    
    int path_query(int x,int y)
    {
        int ans=0;
        while(top[x]!=top[y])
        {
            if(deep[top[x]]<deep[top[y]])
            {
                swap(x,y);
            }
            ans+=query(1,id[top[x]],id[x]);
            x=fa[top[x]];
        }
        if(deep[x]>deep[y])
        {
            swap(x,y);
        }
        ans+=query(1,id[x]+1,id[y]);
        return ans;
    }
    
    
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n-1; i++)
        {
            int from,to;
            scanf("%d%d",&from,&to);
            g[from].push_back(to);
            g[to].push_back(from);
        }
        dfs1(1,0,1);
        dfs2(1,1);
        build(1,1,n);
        for(int i=1; i<=m; i++)
        {
            int from,to;
            char kd;
            scanf("
    %c %d %d",&kd,&from,&to);
            if(kd=='P')
            {
                path_update(from,to,1);
            }
            if(kd=='Q')
            {
                printf("%d
    ",path_query(from,to));
            }
        }
    }
  • 相关阅读:
    springboot项目创建父级依赖
    springboot整合测试
    springboot中使用RedisTemplate实现redis数据缓存
    springboot整合redis
    springboot整合shiro
    配置 maven 环境变量
    虚拟机和主机之间一系列工具包,开启双向复制粘贴后导致的内存占用问题
    mysql服务无法启动的问题
    Linux学习遇到的问题(权限问题:例如无法创建目录"**": 权限不够"等等)
    Windows 10 配置Git 环境变量(还有:安装git后,鼠标右键没有“git bush here”)
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/8658050.html
Copyright © 2011-2022 走看看