题目链接:https://cn.vjudge.net/contest/279350#problem/C

具体思路:单点更新,区间查询,查询的时候有两种操作,查询区间最大值和区间和。

注意点:在查询的时候,我们应该直接将这个点进行查询,而不是荆这个点在树上的编号进行查询,只有在进入线段树的时候我们才用树上的编号,update的时候也就直接用树上的编号就可以了,注意这个题有点权值会有负值的情况。

AC代码:

 #include<iostream>
#include<cstring>
#include<cmath>
#include<stack>
#include<iomanip>
#include<stdio.h>
#include<algorithm>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
# define lson l,m,rt<<
# define rson m+,r,rt<<|
const int maxn = +;
int head[maxn],edgnum,sto[maxn],depth[maxn],Size[maxn],father[maxn];
int son[maxn],ord[maxn],dfsnum,cost[maxn],top[maxn];
int tree1[maxn<<],tree2[maxn<<];
int maxx;
struct node
{
int fr;
int to;
int nex;
} edge[maxn];
void addedge(int fr,int to)
{
edge[edgnum].fr=fr;
edge[edgnum].to=to;
edge[edgnum].nex=head[fr];
head[fr]=edgnum++;
}
void dfs1(int fr,int rt,int dep)
{
depth[fr]=dep;
father[fr]=rt;
son[fr]=-;
Size[fr]=;
for(int i=head[fr]; i!=-; i=edge[i].nex)
{
int to=edge[i].to;
if(to==rt)
continue;
dfs1(to,fr,dep+);
Size[fr]+=Size[to];
if(son[fr]==-||Size[son[fr]]<Size[to])
{
son[fr]=to;
}
}
}
void dfs2(int fr,int rt)
{
ord[fr]=++dfsnum;
top[fr]=rt;
cost[ord[fr]]=sto[fr];
if(son[fr]!=-)
{
dfs2(son[fr],rt);
}
for(int i=head[fr]; i!=-; i=edge[i].nex)
{
int to=edge[i].to;
if(son[fr]!=to&&father[fr]!=to)
{
dfs2(to,to);
}
}
}
void up1(int rt)
{
tree1[rt]=max(tree1[rt<<],tree1[rt<<|]);
}
void up2(int rt)
{
tree2[rt]=tree2[rt<<]+tree2[rt<<|];
}
void buildtree(int l,int r,int rt)
{
if(l==r)
{
tree1[rt]=cost[l];
tree2[rt]=cost[l];
return ;
}
int m=(l+r)>>;
buildtree(lson);
buildtree(rson);
up1(rt);
up2(rt);
}
void query1(int l,int r,int rt,int L,int R)
{
if(L<=l&&R>=r)
{
maxx=max(maxx,tree1[rt]);
return ;
}
int m=(l+r)>>;
if(L<=m)
query1(lson,L,R);
if(R>m)
query1(rson,L,R);
up1(rt);
}
void Query1(int n,int x,int y)
{
maxx=-inf;
int tx=top[x],ty=top[y];
while(tx!=ty)
{
if(depth[tx]<depth[ty])
{
swap(tx,ty);
swap(x,y);
}
query1(,n,,ord[tx],ord[x]);
x=father[tx],tx=top[x];
}
if(depth[x]<depth[y])
{
swap(x,y);
}
query1(,n,,ord[y],ord[x]);
}
int query2(int l,int r,int rt,int L,int R)
{
if(L<=l&&R>=r)
{
return tree2[rt];
}
int ans=;
int m=(l+r)>>;
if(L<=m)
ans+=query2(lson,L,R);
if(R>m)
ans+=query2(rson,L,R);
up2(rt);
return ans;
}
int Query2(int n,int x,int y)
{
int tx=top[x],ty=top[y];
int ans=;
while(tx!=ty)
{
if(depth[tx]<depth[ty])
{
swap(tx,ty);
swap(x,y);
}
ans+=query2(,n,,ord[tx],ord[x]);
x=father[tx],tx=top[x];
}
if(depth[x]<depth[y])
{
swap(x,y);
}
return ans+query2(,n,,ord[y],ord[x]);
}
void update(int l,int r,int rt,int pos,int p)
{
if(l==r)
{
tree1[rt]=p;
tree2[rt]=p;
return ;
}
int m=(l+r)>>;
if(pos<=m)
update(lson,pos,p);
if(pos>m)
update(rson,pos,p);
up1(rt);
up2(rt);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=; i<=n; i++)
{
head[i]=-;
}
int t1,t2;
for(int i=; i<n; i++)
{
scanf("%d %d",&t1,&t2);
addedge(t1,t2);
addedge(t2,t1);
}
for(int i=; i<=n; i++)
{
scanf("%d",&sto[i]);
}
dfs1(,-,);
dfs2(,);
buildtree(,n,);
int q;
char str[];
scanf("%d",&q);
while(q--)
{
scanf("%s",str);
if(str[]=='Q'&&str[]=='M')
{
scanf("%d %d",&t1,&t2);
Query1(n,t1,t2);
printf("%d\n",maxx);
}
else if(str[]=='Q'&&str[]=='S')
{
scanf("%d %d",&t1,&t2);
int ans=Query2(n,t1,t2);
printf("%d\n",ans);
}
else if(str[]=='C')
{
scanf("%d %d",&t1,&t2);
update(,n,,ord[t1],t2);
}
}
return ;
}

数链剖分(树的统计Count )的更多相关文章

  1. 1036: [ZJOI2008]树的统计Count (树链剖分)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3401  Solved: 1418[Submit] ...

  2. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit ...

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

    [ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...

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

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14982  Solved: 6081[Submit ...

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

    树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设( ...

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

    [BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...

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

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit ...

  8. Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 11102  Solved: 4490[Submit ...

  9. BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )

    树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...

  10. Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)

    Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...

随机推荐

  1. 铁大快捷记账Alpha版使用说明书

    一. 引言 (1) 编写目的 (2) 参考资料 (3) 术语和缩写词 二. 网站概述 (1) 网站用途 (2) 网站运行 三. 网站使用过程 (1)网站登录 (2) 功能说明 一.引言 (1)编写目的 ...

  2. 冲刺Two之站立会议8

    今天对软件进行了用户试用,找了一些同学让他们试用软件之后对软件给出了建议,这样我们可以在一定程度上对它进行进一步地优化.

  3. Java实现模拟登录新浪微博

    毕设题目要使用到新浪微博数据,所以要爬取新浪微博的数据.一般而言,新浪微博的爬虫有两种模式:新浪官方API和模拟登录新浪微博.两种方法的异同点和适用情况就无须赘述了.前辈的文章已经非常多了.写这篇文章 ...

  4. Software-Defined Networking:A Comprehensive Survey--Day4

    V. ONGOING RESEARCH EFFORTS AND CHALLENGES 这一节主要介绍了对SDN潜力的发挥有着重要推动作用的一些研究成果. A. Switch Designs 目前Ope ...

  5. PHP 使用GD 库绘制图像,无法显示的问题

    根据官方GD 库绘制图像文档样式 原基本样式 $width = 120; $height = 50; $img = @imagecreatetruecolor($width, $height) or ...

  6. Docker(一)-Docker介绍

    什么就Docker? Docker是一个开源项目, 诞生于2013年初,最初是dotCloud公司内部的一个业余项目.它基于Google公司推出的Go语言实现.项目后来加入了Linux基金会,遵从了A ...

  7. K8S 使用NFS 创建PV和PVC的例子 学习From https://blog.csdn.net/xts_huangxin/article/details/51494472

    1. 获取资料 网址: https://blog.csdn.net/xts_huangxin/article/details/51494472  感谢原作者 这里面 按照自己的机器情况进行了学习模仿 ...

  8. day8——ajax传参到action(Struts2)

    第一种:url+?+参数 jsp中: $(function(){ $("[name='delemp']").click(function(){ $this = $(this); $ ...

  9. 【题解】Friends

    题目描述 有三个好朋友喜欢在一起玩游戏,A君写下一个字符串S,B君将其复制一遍得到T,C君在T的任意位置(包括首尾)插入一个字符得到U.现在你得到了U,请你找出S. 输入输出格式 输入格式 第一行,一 ...

  10. The Super Powers UVA - 11752(合数幂)

    题意: 求1~2^64-1之间所有的 至少是两个不同的正整数的幂的数  升序输出 一个数的合数次幂即为这样的数 找出1~2^64-1中所有数的合数次幂 用set存起来(既能防止重复 又能升序) 最后输 ...