原题

树链剖分板子题

树剖详解:

#include<cstdio>
#include<algorithm>
typedef long long ll;
#define N 30010
using namespace std;
int n,x,y,m,a[N],f[N],dfn[N],deep[N],head[N],cnt=1,tp[N],ref[N],t,son[N],size[N];
char s[10];
struct hhh
{
int to,next;
}edge[2*N];
struct node
{
int l,r,data,mx;
}tre[4*N]; int read()
{
int ans=0,fu=1;
char j=getchar();
for (;(j<'0' || j>'9') && j!='-';j=getchar()) ;
if (j=='-') fu=-1,j=getchar();
for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
return ans*fu;
} void add(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
} void dfs1(int x,int fa,int dep)
{
f[x]=fa;
deep[x]=dep+1;
int mx=0;
for (int i=head[x],v;i;i=edge[i].next)
{
v=edge[i].to;
if (v!=fa)
{
dfs1(v,x,dep+1);
size[x]+=size[v];
if (size[v]>mx) son[x]=v,mx=size[v];
}
}
size[x]++;
} void dfs2(int x,int top)
{
dfn[x]=++t;
ref[t]=x;
tp[x]=top;
if (son[x]) dfs2(son[x],top);
for (int i=head[x],v;i;i=edge[i].next)
{
v=edge[i].to;
if (v!=son[x] && v!=f[x])
dfs2(v,v);
}
} void build(int i,int l,int r)
{
tre[i].l=l;
tre[i].r=r;
if (l==r)
{
tre[i].data=a[ref[l]];
tre[i].mx=a[ref[l]];
return ;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tre[i].data=tre[i*2].data+tre[i*2+1].data;
tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx);
} void modify(int i,int x,int y)
{
if (tre[i].l==x && tre[i].l==tre[i].r)
{
tre[i].data=y;
tre[i].mx=y;
return ;
}
int mid=(tre[i].l+tre[i].r)>>1;
if (x>mid) modify(i*2+1,x,y);
else modify(i*2,x,y);
tre[i].data=tre[i*2].data+tre[i*2+1].data;
tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx);
} ll query(int i,int l,int r,int p)
{
if (tre[i].l==l && tre[i].r==r)
if (p) return tre[i].data;
else return tre[i].mx;
int mid=(tre[i].l+tre[i].r)>>1;
if (l>mid) return query(i*2+1,l,r,p);
else if (r<=mid) return query(i*2,l,r,p);
else if (p) return query(i*2,l,mid,p)+query(i*2+1,mid+1,r,p);
else return max(query(i*2,l,mid,p),query(i*2+1,mid+1,r,p));
} ll pathquery(int u,int v,int p)
{
ll ans=0,tmp=-1000000000;
while (tp[u]!=tp[v])
{
if (deep[tp[u]]<deep[tp[v]]) swap(u,v);
if (p) ans+=query(1,dfn[tp[u]],dfn[u],p);
else tmp=max(tmp,query(1,dfn[tp[u]],dfn[u],p));
u=f[tp[u]];
}
if (deep[u]>deep[v]) swap(u,v);
if (p) return ans+query(1,dfn[u],dfn[v],p);
else return max(tmp,query(1,dfn[u],dfn[v],p));
} int main()
{
n=read();
for (int i=1;i<n;i++)
{
x=read();
y=read();
add(x,y);
add(y,x);
}
for (int i=1;i<=n;i++) a[i]=read();
dfs1(1,0,0);
dfs2(1,1);
build(1,1,n);
m=read();
while (m--)
{
scanf("%s",s);
x=read();
y=read();
if (s[1]=='M')
printf("%lld\n",pathquery(x,y,0));
else if (s[1]=='S')
printf("%lld\n",pathquery(x,y,1));
else modify(1,dfn[x],y);
}
return 0;
}

[bzoj] 1036 Count的更多相关文章

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

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

  2. [BZOJ 1036] [ZJOI2008] 树的统计Count 【Link Cut Tree】

    题目链接:BZOJ - 1036 题目分析 这道题可以用树链剖分,块状树等多种方法解决,也可以使用 LCT. 修改某个点的值时,先将它 Splay 到它所在的 Splay 的根,然后修改它的值,再将它 ...

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

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

  4. BZOJ 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 14354  Solved: 5802 [Subm ...

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

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

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

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

  7. 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count

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

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

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

  9. bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树

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

随机推荐

  1. Easyui下的点击回车键跳转到下个控件

    在Easyui框架下,JavaScript 中的 onKeyDown事件居然失效了.所以使用了另外的函数去实现点击回车键跳转到下个控件. /** * 点击回车键跳转到下个控件; * @param ol ...

  2. c++标准之IO库

    1.面向对象的标准库 2.多种IO标准库工具 istream,提供输入操作 ostream,提供输出操作 cin:读入标准输入的istream对象.全局对象extern std::istream ci ...

  3. Mysql查看锁等信息SQL语句

    查看锁等信息,包括锁信息: select "HOLD:",ph.id h_processid,trh.trx_id h_trx_id,trh.trx_started h_start ...

  4. Windows Server 2012 搭建DHCP及远程路由访问

    1.1    基础环境信息 1.2    DHCP与远程访问服务器角色安装 1.服务器管理器—>仪表板—>添加角色和功能,出现添加角色和功能向导,点击下一步 2.选择安装类型为基于角色或基 ...

  5. JavaScript---ECMA对象

    1.对象的概念及分类 1.1 ECMAScript中没有类,但定义了“对象”,逻辑上等价于其他程序设计语言中的类. var o = new Object(); 1.2 本地对象(native obje ...

  6. 柱状图多系列php动态实现(ec)

    <?php require_once 'data.php'; $arr1=$a->sum('answer','ask_id=1'); $arr2=$a->sum('answer',' ...

  7. POJ3246

    Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same ...

  8. JAVA运行机制

    这一篇我们来简单理解一下JAVA的运行机制 大概可以分为三大部分 1.编写程序 2.编译程序 3.运行程序 1.编写程序 编写程序就是我们前面说的源代码 这些源代码都有特殊的语法 例如main函数 他 ...

  9. AD9 设置网络标号作用域

    http://blog.sina.com.cn/s/blog_99c8ec600102uxul.html 1.版本:Altium Designer 10 2.原因:在进行多原理图设计时, 不同原理图之 ...

  10. 线程间通信(等待,唤醒)&Java中sleep()和wait()比较

    1.什么是线程间通信? 多个线程在处理同一资源,但是任务却不同. 生活中栗子:有一堆煤,有2辆车往里面送煤,有2辆车往外拉煤,这个煤就是同一资源,送煤和拉煤就是任务不同. 2.等待/唤醒机制. 涉及的 ...