题目链接: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. Asp.Net Core--基于声明的授权

    翻译如下: 当创建身份时,其可以被分配由可信方发布的一个或多个声明. 索赔是名称值对,表示主题是什么,而不是主体可以做什么. 例如,您可能有驾驶执照,由当地驾驶执照颁发. 您的驾驶执照上有您的出生日期 ...

  2. 通过工厂方式配置bean

    src\dayday\CarFactoryBean.java package dayday;import org.springframework.beans.factory.FactoryBean;/ ...

  3. Xcode换版本或者改名字后无法使用simpholders2

    修改一下路径,在终端下输入下面的命令sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer 敲回车后 ...

  4. 利用python进行数据分析之数据聚合和分组运算

    对数据集进行分组并对各分组应用函数是数据分析中的重要环节. group by技术 pandas对象中的数据会根据你所提供的一个或多个键被拆分为多组,拆分操作是在对象的特定轴上执行的,然后将一个函数应用 ...

  5. 王垠:Lisp 已死,Lisp 万岁!

    王垠:Lisp 已死,Lisp 万岁!_IT新闻_博客园 王垠:Lisp 已死,Lisp 万岁!

  6. [命令行] curl查询公网出口IP

    转载:http://blog.csdn.net/orangleliu/article/details/51994513 不管是在家里还是办公室,或者是公司的主机,很多时候都是在内网中,也就是说很多都是 ...

  7. web前端开发面试题(未完待续)

    一.HTML与XHTML的不同:1)XHTML元素必须被正确地嵌套 2)元素必须被关闭   如:<h1>--</h1>关闭 3)标签名必须用小写字母 4)XHTML文档必须有根 ...

  8. phpcms V9 默认模板文件目录结构_PHPCms教程

    PHPCMSV9 默认模板目录结构 templates   框架系统模板目录            announce    公告                show.html       内容页  ...

  9. java改单个插入为批量插入

    单条insert into table value() 13W数据需要执行7小时 变成inert into table value(),(),(),(),() inert into table val ...

  10. recovery 升级过程LED灯闪烁

    Android设备在进入recovery升级的过程,我们在屏幕上面可以看到升级的机器人动画,以及升级的进度显示.这仅限于有屏幕的设备,比如平板PAD,电视TV等,对与没有屏幕的盒子BOX,那么在不接入 ...