题目传送门:1036: [ZJOI2008]树的统计Count

  这道题是我第一次打树剖的板子,虽然代码有点长,但是“打起来很爽”,而且整道题只花了不到1.5h+,还是一遍过样例!一次提交AC!(难道前天膜cyc神犇真的起作用了?)

  按捺不住激动的心情!!!

  这道题是树剖+线段树模板题,树剖把树转化成线段后就可以单点修改+区间求和/区间求max了。

  又臭又长的93行代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct point{
int sum,max;
}a[];
int fir[],to[],ne[];
int vis[],fa[],dep[],size[],hson[],top[],id[];
int tot,n,m,q;
char s[];
void change(int now,int l,int r,int x,int k)
{
if(l==r)a[now].sum=a[now].max=k;
else{
int mid=(l+r)>>;
if(x<=mid)change(now<<,l,mid,x,k);else change(now<<|,mid+,r,x,k);
a[now].sum=a[now<<].sum+a[now<<|].sum; a[now].max=max(a[now<<].max,a[now<<|].max);
}
}
int getsum(int now,int l,int r,int x,int y)
{
if(x<=l&&r<=y)return a[now].sum;
else{
int mid=(l+r)>>,sum=;
if(x<=mid)sum+=getsum(now<<,l,mid,x,y);
if(mid<y)sum+=getsum(now<<|,mid+,r,x,y);
return sum;
}
}
int getmax(int now,int l,int r,int x,int y)
{
if(x<=l&&r<=y)return a[now].max;
else{
int mid=(l+r)>>,mx=-<<;
if(x<=mid)mx=max(mx,getmax(now<<,l,mid,x,y));
if(mid<y)mx=max(mx,getmax(now<<|,mid+,r,x,y));
return mx;
}
}
void add(int x,int y){to[++tot]=y; ne[tot]=fir[x]; fir[x]=tot;}
void dfs1(int now,int d)
{
int i,mxson=; size[now]=; vis[now]=; dep[now]=d;
for(i=fir[now];i;i=ne[i])
if(!vis[to[i]]){
fa[to[i]]=now; dfs1(to[i],d+);
if(size[to[i]]>mxson)mxson=size[to[i]],hson[now]=to[i];
size[now]+=size[to[i]];
}
}
void dfs2(int now,int tp)
{
int i;
top[now]=tp; id[now]=++tot;
if(hson[now])dfs2(hson[now],tp);
for(i=fir[now];i;i=ne[i])
if(to[i]!=hson[now]&&to[i]!=fa[now])dfs2(to[i],to[i]);
}
int main()
{
int i,x,y;
scanf("%d",&n); tot=;
for(i=;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
for(i=;i<=n;i++)vis[i]=; tot=;
dfs1(,); dfs2(,);
for(i=;i<=n;i++)scanf("%d",&x),change(,,n,id[i],x);
scanf("%d",&q);
for(i=;i<=q;i++){
scanf("%s%d%d",s,&x,&y);
if(s[]=='C')change(,,n,id[x],y);
else if(s[]=='M'){
int mx=-<<;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){int tmp=x; x=y; y=tmp;}
mx=max(mx,getmax(,,n,id[top[x]],id[x])); x=fa[top[x]];
}
if(dep[x]>dep[y]){int tmp=x; x=y; y=tmp;}
printf("%d\n",max(mx,getmax(,,n,id[x],id[y])));
}
else{
int sum=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){int tmp=x; x=y; y=tmp;}
sum+=getsum(,,n,id[top[x]],id[x]); x=fa[top[x]];
}
if(dep[x]>dep[y]){int tmp=x; x=y; y=tmp;}
printf("%d\n",sum+getsum(,,n,id[x],id[y]));
}
}
}

树链剖分+线段树

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. 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 ...

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

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

随机推荐

  1. cocos2d-x学习日志(18) --程序是怎样開始执行与结束?

    问题的由来 怎么样使用 Cocos2d-x 高速开发游戏.方法非常easy,你能够看看其自带的例程,或者从网上搜索教程,执行起第一个HelloWorld,然后在 HelloWorld 里面写相关逻辑代 ...

  2. charles_https_通过模拟器安装APP然后抓包

    声明,方法参考链接:https://bbs.pediy.com/thread-226435.htm 使用文中的模拟器并不好使,自个使用逍遥模拟器的4.4版本成功抓包, 1>下载逍遥模拟器,在逍遥 ...

  3. ViewPager页面切换特效

    ViewPager页面切换特效如下效果 看效果: 效果1: 效果2: 下面就开始讲解如何实现这两个页面翻转效果 1.首先你得会ViewPager控件的使用(废话!现在还有人不会使用吗???!!) 2. ...

  4. hdu 3667 (拆边 mcmf)

    注意题目中 边的容量 <= 5.可以把费用权值 a *f ^2化归成 a * f2, 即第一条边费用为 1 * a, 第二条 为 (4 - 1) * a, 第三条为 (9  - 4) * a.. ...

  5. 记录--java 分页 思路 (hibernate关键代码)

    有时会脑袋蒙圈,记录下分页的思路 下面代码是hibernate的分页,其分页就是从第几条数据为起点,取几条数据.比如在mysql中的limit(5,10)取的就是第6条到第10条 在下面代码中的pag ...

  6. coursera 《现代操作系统》 -- 第十周 文件系统(2)

    身份验证 Authentication 知道用户是谁.通过账号密码.Id 这样的识别出来. 访问控制 Permission 知道用户是谁后. 主动控制 记录用户ID和对应的访问权限 --> 记录 ...

  7. Martin Fowler’s Active Record design pattern.

    P of EAA: Active Record https://www.martinfowler.com/eaaCatalog/activeRecord.html Active Record An o ...

  8. HTTP headers with the Link header field HTTP协议支持分页(Pagination)操作,在Header中使用 Link 即可

    RFC 5988 - Web Linking  https://tools.ietf.org/html/rfc5988#section-5.1 https://www.zhihu.com/questi ...

  9. Armijo-Goldstein准则与Wolfe-Powell准则

    Armijo-Goldstein准则与Wolfe-Powell准则是不精确的一维搜索的两大准则. 之所以要遵循这些准则是为了能使算法收敛(求最优解).即要使我们的不精确的一维搜索的步长满足一定的规则, ...

  10. C#对Excel中指定一列或一行实现隐藏或显示!

    C#对Excel中指定一列或一行实现隐藏或显示!不会,求指导!