【JSOI2008】【BZOJ1036】【LCT版】树的统计Count

如今我终于来用LCT做这个题了QwQ

Description

一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

Input

输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

Output

对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

Sample Input

4

1 2

2 3

4 1

4 2 1 3

12

QMAX 3 4

QMAX 3 3

QMAX 3 2

QMAX 2 3

QSUM 3 4

QSUM 2 1

CHANGE 1 5

QMAX 3 4

CHANGE 3 6

QMAX 3 4

QMAX 2 4

QSUM 3 4

Sample Output

4

1

2

2

10

6

5

6

5

16

HINT

Source

树的分治

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL long long
#define MAXN 50010
#define MAXINT 0x7fffffff
using namespace std;
struct splay
{
    int fa,ch[2];
    LL sum,maxn,w;
    bool rev;
}tree[MAXN];
int q[MAXN],top;
char ch[10];
void print();
long long U,V,n,m,u[MAXN],v[MAXN];
inline void in(long long &x)
{
    int flag=1;char ch=getchar();x=0;
    while (!(ch>=‘0‘&&ch<=‘9‘)) flag=ch==‘-‘?-1:1,ch=getchar();
    while (ch>=‘0‘&&ch<=‘9‘)    x=x*10+ch-‘0‘,ch=getchar();x*=flag;
}
inline bool is_root(int x)
{
    return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;
}
inline void push_up(int x)
{
    tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].w;
    tree[x].maxn=max(tree[x].w,max(tree[tree[x].ch[0]].maxn,tree[tree[x].ch[1]].maxn));
}
inline void push_down(int x)
{
    if (tree[x].rev)
    {
        tree[x].rev^=1;tree[tree[x].ch[0]].rev^=1;tree[tree[x].ch[1]].rev^=1;
        swap(tree[x].ch[0],tree[x].ch[1]);
    }
}
inline void rot(int x)
{
    int y=tree[x].fa,z=tree[y].fa,l,r;
    l=(tree[y].ch[1]==x);r=l^1;
    if (!is_root(y))    tree[z].ch[(tree[z].ch[1]==y)]=x;
    tree[tree[x].ch[r]].fa=y;tree[y].fa=x;tree[x].fa=z;
    tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y;
    push_up(y);push_up(x);
}
inline void Splay(int x)
{
    q[++top]=x;
    for (int i=x;!is_root(i);i=tree[i].fa)  q[++top]=tree[i].fa;
    while (top) push_down(q[top--]);
    while (!is_root(x))
    {
        int y=tree[x].fa,z=tree[y].fa;
        if (!is_root(y))
        {
            if (tree[y].ch[0]==x^tree[z].ch[0]==y)  rot(x);
            else    rot(y);
        }
        rot(x);
    }
}
inline void access(int x)
{
    for (int t=0;x;t=x,x=tree[x].fa)    Splay(x),tree[x].ch[1]=t,push_up(x);
}
inline void make_root(int x)
{
    access(x);Splay(x);tree[x].rev^=1;
}
inline void link(int x,int y)
{
    make_root(x);tree[x].fa=y;
}
inline void cut(int x,int y)
{
    make_root(x);access(y);Splay(y);
}
int main()
{
    in(n);tree[0].maxn=-MAXINT;
    for (int i=1;i<n;i++)   in(u[i]),in(v[i]);
    for (int i=1;i<=n;i++)  in(tree[i].w),tree[i].sum=tree[i].maxn=tree[i].w;
    for (int i=1;i<n;i++)   link(u[i],v[i]);
    in(m);
    while (m--)
    {
        scanf("%s",ch);in(U);in(V);
        if (ch[1]==‘H‘) Splay(U),tree[U].w=V,push_up(U);
        if (ch[1]==‘M‘) cut(U,V),printf("%lld\n",tree[V].maxn);
        if (ch[1]==‘S‘) cut(U,V),printf("%lld\n",tree[V].sum);
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 20:48:31

【JSOI2008】【BZOJ1036】【LCT版】树的统计Count的相关文章

【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身 Input 输入的第一行为一个整数n,表示节点的个数.接下来n

[BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分

树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设(u,v)为轻边,则size(v)<=size(u)/2 (一旦大于了那必然是重边) 也就是一条路径上每增加一条轻边节点个数就会减少一半以上,那么显然根到任意一个节点路径上的轻边条数一定不会超过log(n)(不然节点就没了啊23333) 重链定义为一条极长的连续的且全由重边构成的链. 容易看出重链两两

bzoj1036: [ZJOI2008]树的统计Count(树链剖分+线段树维护)

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

BZOJ1036: [ZJOI2008]树的统计Count - 树链剖分 -

1036: [ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身 Input 输入的第一行为一个整数n,表示节点的个数.接下来n – 1

[ZJOI2008][BZOJ1036] 树的统计count

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

【bzoj1036】【ZJOI2008】【树的统计Count】

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

bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题

[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身 Input 输入的第一行为一个整数n,表示节点的个数.接下来n – 1行,每行

BZOJ 题目1036: [ZJOI2008]树的统计Count(Link Cut Tree,修改点权求两个最大值和最大值)

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

BZOJ 题目1036: [ZJOI2008]树的统计Count(Link Cut Tree,改动点权求两个最大值和最大值)

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

BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)

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