bzoj 4372: 烁烁的游戏 动态点分治_树链剖分_线段树

Code:

#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 6011111
#define N 500010
#define inf 0x7f7f7f
using namespace std;
int hd[N],nx[N],to[N],cnt;
int n,m,val[N],vis[N];
void add(int u,int v)
{
    nx[++cnt]=hd[u],hd[u]=cnt,to[cnt]=v;
}
namespace heavyedge{
    int dep[N],hson[N],fa[N],siz[N],top[N];
    void dfs1(int u,int ff)
    {
        dep[u]=dep[ff]+1,fa[u]=ff,siz[u]=1;
        for(int i=hd[u];i;i=nx[i])
            if(to[i]!=ff)
            {
                dfs1(to[i],u),siz[u]+=siz[to[i]];
                if(siz[to[i]]>siz[hson[u]]) hson[u]=to[i];
            }
    }
    void dfs2(int u,int tp)
    {
        top[u]=tp;
        if(hson[u]) dfs2(hson[u],tp);
        for(int i=hd[u];i;i=nx[i])
        {
            if(to[i]==fa[u]||to[i]==hson[u]) continue;
            dfs2(to[i],to[i]);
        }
    }
    int LCA(int u,int v)
    {
        while(top[u]!=top[v]) dep[top[u]] < dep[top[v]] ? v = fa[top[v]] : u = fa[top[u]];
        return dep[u] < dep[v] ? u : v;
    }
    int main()
    {
        dfs1(1,0), dfs2(1,1);
        return 0;
    }
};
int Dis(int u,int v)
{
    return heavyedge::dep[u] + heavyedge::dep[v] - (heavyedge::dep[heavyedge::LCA(u,v)] << 1);
}
int siz[N],f[N],root,sn,Fa[N];
int GetRoot(int u,int ff)
{
    siz[u] = 1,f[u] = 0;
    for(int i = hd[u]; i ; i = nx[i])
    {
        if(to[i] == ff || vis[to[i]]) continue;
        GetRoot(to[i],u);
        siz[u] += siz[to[i]];
        f[u] = max(f[u],siz[to[i]]);
    }

    f[u] = max(f[u],sn - siz[u]);
    if(f[u] < f[root]) root = u;
}
void dfs(int u)
{
    vis[u] = 1;
    for(int i = hd[u]; i ; i = nx[i])
    {
        if(vis[to[i]]) continue;
        root = 0, sn = siz[to[i]], GetRoot(to[i],u);
        Fa[root] = u, dfs(root);
    }
}
struct Segment_Tree{
    #define ls (t[o].l)
    #define rs (t[o].r)
    int tot;
    struct Node
    {
        int l,r,v;
    }t[maxn<<1];
    void update(int &o,int l,int r,int p,int w)
    {
        if(!o) o = ++cnt;
        t[o].v += w;
        if(l == r) return;
        int mid = (l + r) >> 1;
        if(p <= mid) update(t[o].l,l,mid,p,w);
        else update(t[o].r,mid + 1,r,p,w);
    }

    int query(int o,int l,int r,int L,int R)
    {
        if(!o || l > r) return 0;
        if(l >= L && r <= R) return t[o].v;
        int mid = (l + r) >> 1,res = 0;
        if(L <= mid) res += query(t[o].l,l,mid,L,R);
        if(R >= mid + 1) res += query(t[o].r,mid + 1,r, L,R);
        return res;
    }
}T;
int ans = 0,rt[N];
#define fax(x) (x + n)
void Update(int x,int k,int w)
{
    T.update(rt[x],0,n,0,w),T.update(rt[x],0,n,k + 1,-w);
    for(int i = x; Fa[i]; i = Fa[i])
    {
        int dis = Dis(x, Fa[i]);
        if(k - dis < 0) continue;
        T.update(rt[Fa[i]],0,n,0,w),T.update(rt[Fa[i]],0,n,k - dis + 1,-w);
        T.update(rt[fax(i)],0,n,0,w),T.update(rt[fax(i)],0,n,k - dis + 1,-w);
    }
}
int Query(int x)
{
    int res = T.query(rt[x],0,n,0,0);
    for(int i = x; Fa[i] ; i = Fa[i])
    {
        int dis = Dis(x, Fa[i]);
        res += T.query(rt[Fa[i]],0,n,0,dis);
        res -= T.query(rt[fax(i)],0,n,0,dis);
    }
    return res;
}
char str[20];
int main()
{
    // setIO("input");
    scanf("%d%d",&n,&m);
    for(int i = 1,u,v;i < n; ++i)  scanf("%d%d",&u,&v), add(u,v),add(v,u);
    heavyedge :: main();
    f[0] = inf, sn = n,root = 0,GetRoot(1,0), dfs(root);
    while(m--)
    {
        int x,y,z;
        scanf("%s",str);
        if(str[0] == ‘M‘) scanf("%d%d%d",&x,&y,&z),Update(x,y,z);
        if(str[0] == ‘Q‘) scanf("%d",&x), printf("%d\n",Query(x));
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/guangheli/p/10921268.html

时间: 2024-08-06 11:00:43

bzoj 4372: 烁烁的游戏 动态点分治_树链剖分_线段树的相关文章

数据结构(树链剖分,线段树):SDOI 2016 游戏

4515: [Sdoi2016]游戏 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 351  Solved: 157[Submit][Status][Discuss] Description Alice 和 Bob 在玩一个游戏. 游戏在一棵有 n 个点的树上进行.最初,每个点上都只有一个数字,那个数字是 123456789123456789. 有时,Alice 会选择一条从 s 到 t 的路径,在这条路径上的每一个点上都添加一个数字.对于路径上

BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)

[ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14968  Solved: 6079[Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I II.

bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)

3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1272  Solved: 451[Submit][Status][Discuss] Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先. 有q次询问,每次询问给出l r z,求sigma_{l<=i<=r}dep[

bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)

3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 876  Solved: 446[Submit][Status][Discuss] Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们用不同的正整数代表 各种宗教,  S国的居民常常旅行.旅行时他们总

bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit][Status][Discuss] Description 一 棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值

bzoj 4372 烁烁的游戏 —— 点分治+树状数组

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4372 本以为和 bzoj3730 一样,可以直接双倍经验了: 但要注意一下,树状数组不能查询0位置,所以再开一个 w 数组记录: 论 if 和 continue 的不同...如果要用到两个值,不要判断第一个后就 continue ... 代码如下: #include<cstdio> #include<cstring> #include<algorithm> #in

BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status][Discuss] Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询问给出l r z,求sigma_{l<=i<=r}dep[LC

Tsinsen A1517. 动态树 树链剖分,线段树,子树操作

题目 : http://www.tsinsen.com/A1517 A1517. 动态树 时间限制:3.0s   内存限制:1.0GB 总提交次数:227   AC次数:67   平均分:49.52 将本题分享到: 查看未格式化的试题   提交   试题讨论 试题来源 中国国家队清华集训 2013-2014 第四天 问题描述 小明在楼下种了一棵动态树, 该树每天会在某些节点上长出一些果子. 这棵树的根节点为1, 它有n个节点, n-1条边. 别忘了这是一棵动态树, 每时每刻都是动态的. 小明要求

树链剖分教程 &amp; bzoj 1036 [ZJOI2008] 树的统计 Count 题解

转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24669751 [原题] 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4465  Solved: 1858 [Submit][Status] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I