入门题 + 熟悉代码

/**************************************************************
Problem: 1036
User: 96655
Language: C++
Result: Accepted
Time:2472 ms
Memory:5536 kb
****************************************************************/ #include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
#include<cstdlib>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<cmath>
#include<stack>
#include<utility>
using namespace std;
const int maxn=;
struct Edge
{
int v,next;
} edge[maxn*];
int va[maxn],p,head[maxn],clk,n;
void init()
{
memset(head,-,sizeof(head));
p=clk=;
}
void addedge(int u,int v)
{
edge[p].v=v;
edge[p].next=head[u];
head[u]=p++;
}
int id[maxn],sz[maxn],dep[maxn],fa[maxn],son[maxn],top[maxn];
int xx[maxn];
void dfs1(int u,int f,int d)
{
dep[u]=d;
fa[u]=f;
sz[u]=;
son[u]=-;
for(int i=head[u]; ~i; i=edge[i].next)
{
int v=edge[i].v;
if(v==f)continue;
dfs1(v,u,d+);
sz[u]+=sz[v];
if(son[u]==-||sz[v]>sz[son[u]])
son[u]=v;
}
}
void dfs2(int u,int tp)
{
id[u]=++clk;
xx[id[u]]=va[u];
top[u]=tp;
if(son[u]!=-)dfs2(son[u],tp);
for(int i=head[u]; ~i; i=edge[i].next)
{
int v=edge[i].v;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
int sum[maxn*],maxv[maxn*];
void pushup(int rt)
{
sum[rt]=sum[rt*]+sum[rt*+];
maxv[rt]=max(maxv[rt*],maxv[rt*+]);
}
void build(int rt,int l,int r)
{
if(l==r)
{
sum[rt]=maxv[rt]=xx[l];
return;
}
int m=(l+r)>>;
build(rt*,l,m);
build(rt*+,m+,r);
pushup(rt);
}
void update(int rt,int l,int r,int pos,int c)
{
if(l==r)
{
maxv[rt]=sum[rt]=c;
return;
}
int m=(l+r)>>;
if(pos<=m)update(rt*,l,m,pos,c);
else update(rt*+,m+,r,pos,c);
pushup(rt);
}
int query1(int rt,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
{
return sum[rt];
}
int ans=;
int m=(l+r)>>;
if(x<=m)ans+=query1(rt*,l,m,x,y);
if(y>m)ans+=query1(rt*+,m+,r,x,y);
return ans;
}
int query2(int rt,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
{
return maxv[rt];
}
int ans=-;
int m=(l+r)>>;
if(x<=m)ans=max(ans,query2(rt*,l,m,x,y));
if(y>m)ans=max(ans,query2(rt*+,m+,r,x,y));
return ans;
}
int getsum(int u,int v)
{
int ans=;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
swap(u,v);
ans+=query1(,,n,id[top[u]],id[u]);
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
ans+=query1(,,n,id[u],id[v]);
return ans;
}
int getmax(int u,int v)
{
int ans=-;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
swap(u,v);
ans=max(ans,query2(,,n,id[top[u]],id[u]));
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
ans=max(ans,query2(,,n,id[u],id[v]));
return ans;
}
int main()
{
while(~scanf("%d",&n))
{
init();
for(int i=; i<n; ++i)
{
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
for(int i=; i<=n; i++)
scanf("%d",&va[i]);
dfs1(,,);
dfs2(,);
build(,,n);
int q;
scanf("%d",&q);
while(q--)
{
char s[];
int x,y;
scanf("%s%d%d",s,&x,&y);
if(s[]=='Q')
{
if(s[]=='M') printf("%d\n",getmax(x,y));
else printf("%d\n",getsum(x,y));
}
else update(,,n,id[x],y);
}
}
return ;
}

bzoj1036: [ZJOI2008]树的统计Count 树链剖分+线段树的更多相关文章

  1. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  2. 【bzoj1036】树的统计[ZJOI2008]树链剖分+线段树

    题目传送门:1036: [ZJOI2008]树的统计Count 这道题是我第一次打树剖的板子,虽然代码有点长,但是“打起来很爽”,而且整道题只花了不到1.5h+,还是一遍过样例!一次提交AC!(难道前 ...

  3. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  4. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  5. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  6. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  7. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  8. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  9. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  10. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

随机推荐

  1. hdu 4277 USACO ORZ

    没什么好方法,只能用dfs了. 代码如下: #include<iostream> #include<cstring> #include<cstdio> #inclu ...

  2. lintcode 中等题:permutations 全排列

    题目 全排列 给定一个数字列表,返回其所有可能的排列. 您在真实的面试中是否遇到过这个题? Yes 样例 给出一个列表[1,2,3],其全排列为: [ [1,2,3], [1,3,2], [2,1,3 ...

  3. [转]C++常见内存错误汇总

    在系统开发过程中出现的bug相对而言是比较好解决的,花费在这个上面的调试代价不是很大,但是在系统集成后的bug往往是难以定位的bug(最好方式是打桩,通过打桩可以初步锁定出错的位置,如:进入函数前打印 ...

  4. 【Linux高频命令专题(21)】df

    概述 linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息. 显示指定磁盘文件的可用空间.如果没有文件名 ...

  5. MIT算法导论——第三讲.The Divide-and-Conquer

    本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...

  6. Hibernate逍遥游记-第8章 映射组成关系(<component>、<parent>)

    一. 1. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...

  7. Maven那点事儿(Eclipse版)

    Maven那点事儿(Eclipse版)   前言: 由于最近工作学习,总是能碰到Maven的源码.虽然平时工作并不使用Maven,但是为了学习一些源码,还是必须要了解下.这篇文章不是一个全面的Mave ...

  8. Map集合案例

    1.获取字符串中每一个字母出现的次数. 比如"aababcabcdabcde",结果为:a(5)b(4)c(3)d(2)e(1) 分析如下: package mapexercise ...

  9. 在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)

    这里,我们不会为真实的硬件设备编写内核驱动程序.为了方便描述为Android系统编写内核驱动程序的过程,我们使用一个虚拟的硬件设备,这个设备只有一个4字节的寄存器,它可读可写.想起我们第一次学习程序语 ...

  10. MyEclipse开发WebService教程

    . 创建一个 webService 工程. 2. 创建一个普通 Java 类   3. 创建 webService 服务端 HelloJaxwsDelegate.java 的源代码如下:   4. 导 ...