【BZOJ2325】[ZJOI2011]道馆之战 线段树+树链剖分
【BZOJ2325】[ZJOI2011]道馆之战
Description

Input
Output
包含若干行,每行一个整数。即对于输入中的每个询问,依次输出一个答案。
Sample Input
1 2
2 3
2 4
1 5
.#
..
#.
.#
..
Q 5 3
C 1 ##
Q 4 5
Sample Output
3
题解:显然的线段树+树剖,但是线段树要维护些什么呢?f[0/1][0/1]表示从左边的A/B区域走到右边的A/B区域最多能踩多少冰块,lm[0/1]代表从左边的A/B区域往右走最多能踩多少冰块,rm[0/1]代表从右边的A/B区域往左走最多能踩多少冰块。在区间合并的时候维护这3个东西。并且不难发现,这3个东西是支持翻转操作的,所以查询的时候就容易多了。
#include <cstdio>
#include <cstring>
#include <iostream>
#define lson x<<1
#define rson x<<1|1
using namespace std;
const int maxn=30010;
const int inf=0x1f1f1f1f;
int max(int a,int b,int c) {return max(max(a,b),c);}
int n,m,cnt,ans;
int siz[maxn],dep[maxn],fa[maxn],son[maxn],top[maxn],to[maxn<<1],next[maxn<<1],head[maxn],st[maxn],p[maxn],q[maxn];
int v[maxn][2];
char str[10];
struct node
{
int a[2][2],lm[2],rm[2];
node () {memset(a,0,sizeof(a)),memset(lm,0,sizeof(lm)),memset(rm,0,sizeof(rm));}
node (int _)
{
lm[0]=rm[0]=max(v[_][0],v[_][0]+v[_][1],0),a[0][0]=v[_][0];
lm[1]=rm[1]=max(v[_][1],v[_][0]+v[_][1],0),a[1][1]=v[_][1];
a[0][1]=a[1][0]=v[_][0]+v[_][1];
}
int * operator [] (int b){return a[b];}
void rev()
{
swap(a[0][1],a[1][0]),swap(lm[0],rm[0]),swap(lm[1],rm[1]);
}
node operator + (node b)
{
node c;
c[0][0]=max(a[0][0]+b[0][0],a[0][1]+b[1][0],-inf);
c[0][1]=max(a[0][0]+b[0][1],a[0][1]+b[1][1],-inf);
c[1][0]=max(a[1][0]+b[0][0],a[1][1]+b[1][0],-inf);
c[1][1]=max(a[1][0]+b[0][1],a[1][1]+b[1][1],-inf);
c.lm[0]=max(lm[0],a[0][0]+b.lm[0],a[0][1]+b.lm[1]);
c.lm[1]=max(lm[1],a[1][0]+b.lm[0],a[1][1]+b.lm[1]);
c.rm[0]=max(b.rm[0],rm[0]+b[0][0],rm[1]+b[1][0]);
c.rm[1]=max(b.rm[1],rm[0]+b[0][1],rm[1]+b[1][1]);
return c;
}
}s[maxn<<2];
inline void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[x])
{
fa[to[i]]=x,dep[to[i]]=dep[x]+1,dfs1(to[i]),siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
}
}
void dfs2(int x,int tp)
{
top[x]=tp,p[x]=++p[0],q[p[0]]=x;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[x]&&to[i]!=son[x]) dfs2(to[i],to[i]);
}
void build(int l,int r,int x)
{
if(l==r)
{
s[x]=node(q[l]);
return ;
}
int mid=(l+r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
s[x]=s[lson]+s[rson];
}
void updata(int l,int r,int x,int a)
{
if(l==r)
{
s[x]=node(q[l]);
return ;
}
int mid=(l+r)>>1;
if(a<=mid) updata(l,mid,lson,a);
else updata(mid+1,r,rson,a);
s[x]=s[lson]+s[rson];
}
node query(int l,int r,int x,int a,int b)
{
if(a<=l&&r<=b) return s[x];
int mid=(l+r)>>1;
if(b<=mid) return query(l,mid,lson,a,b);
if(a>mid) return query(mid+1,r,rson,a,b);
return query(l,mid,lson,a,b)+query(mid+1,r,rson,a,b);
}
void ask(int x,int y)
{
node sx,sy,t;
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]]) t=query(1,n,1,p[top[x]],p[x]),t.rev(),sx=sx+t,x=fa[top[x]];
else sy=query(1,n,1,p[top[y]],p[y])+sy,y=fa[top[y]];
}
if(dep[x]>dep[y]) t=query(1,n,1,p[y],p[x]),t.rev(),sx=sx+t;
else sy=query(1,n,1,p[x],p[y])+sy;
sx=sx+sy;
printf("%d\n",max(sx.lm[0],sx.lm[1]));
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,a,b;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
dep[1]=1,dfs1(1),dfs2(1,1);
for(i=1;i<=n;i++) scanf("%s",str),v[i][0]=(str[0]=='.')?1:-inf,v[i][1]=(str[1]=='.')?1:-inf;
build(1,n,1);
for(i=1;i<=m;i++)
{
scanf("%s",str);
if(str[0]=='Q') a=rd(),b=rd(),ask(a,b);
else a=rd(),scanf("%s",str),v[a][0]=(str[0]=='.')?1:-inf,v[a][1]=(str[1]=='.')?1:-inf,updata(1,n,1,p[a]);
}
return 0;
}//5 3 1 2 2 3 2 4 1 5 .# .. #. .# .. Q 5 3 C 1 ## Q 4 5
【BZOJ2325】[ZJOI2011]道馆之战 线段树+树链剖分的更多相关文章
- BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树
题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...
- bzoj2325 [ZJOI2011]道馆之战
Description 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个 ...
- BZOJ2325 [ZJOI2011]道馆之战 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2325 题意概括 给你一棵N个点的树,树上的每个节点有A,B两块区域,且每种区域有两种状态:可以走的 ...
- bzoj2325 [ZJOI2011]道馆之战 树链剖分+DP+类线段树最大字段和
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2325 题解 可以参考线段树动态维护最大子段和的做法. 对于线段树上每个节点 \(o\),维护 ...
- bzoj千题计划243:bzoj2325: [ZJOI2011]道馆之战
http://www.lydsy.com/JudgeOnline/problem.php?id=2325 设线段树节点区间为[l,r] 每个节点维护sum[0/1][0/1] 从l的A/B区域到r的 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并
题目描述 给定一棵树,每个节点有上下两个格子,每个格子的状态为能走或不能走.m次操作,每次修改一个节点的状态,或询问:把一条路径上的所有格子拼起来形成一个宽度为2的长方形,从起点端两个格子的任意一个开 ...
- 【题解】Luogu P4679 [ZJOI2011]道馆之战
原题传送门 码农题树剖好题,口袋妖怪是个好玩的游戏 这道题要用树链剖分,我博客里有对树链剖分的详细介绍 下文左右就代表树的节点按dfs序后的左右,上.下分别表示每个节点的A.B区域 考虑在链上的情况, ...
- 线段树&数链剖分
傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...
随机推荐
- 60分钟搞定JAVA加解密
从摩尔电码到小伙伴之间老师来了的暗号,加密信息无处不在.从军事到生活,加密信息的必要性也不言而喻. 今天,我们就来看看java怎么对数据进行加解密 分类 a.古典密码 -- 受限制算法:算法的保密性给 ...
- C# 0-1背包问题
0-1背包问题 0-1背包问题基本思想: p[i,j]表示在前面i个物品总价值为j时的价值最大值.str[i, j]表示在前面i个物品总价值为j时的价值最大值时的物品重量串. i=0 或者j=0时: ...
- annex-b格式
annex-b格式 总的来说H264的码流的打包方式有两种,一种为annex-b byte stream format的格式,这个是绝大部分编码器的默认输出格式,就是每个帧的开头的3~4个字节是H26 ...
- 火车票抢票API 根据乘客的车次与座席要求快速订票出票
火车票抢票API 根据乘客的车次与座席要求快速订票出票:https://www.juhe.cn/docs/api/id/257 1.站站查询 接口地址:http://v.juhe.cn/grabTic ...
- Django——QuerySets酷毙了!
Django的QuerySets酷毙了! 在本文中我将解释一下QuerySets是什么,它是如何工作的(如果你对它已经熟悉了,你可以直接跳到第二部分),我认为如果可以的话你应该总是返回QuerySet ...
- Web前端开发实战1:二级下拉式菜单之CSS实现
二级下拉式菜单在各大学校站点.电商类站点.新闻类站点等大型?站点非经常见,那么它的实现原理是什么呢? 学习了Web前端开发的知识后,我们是能够实现这种功能的.复杂的都是从基础效果上加入做出来的.原理和 ...
- strults2标签s:set的用法
struts2标签<s:set></s:set>的用法.原理 http://liuna718-163-com.iteye.com/blog/1124654 我的例子: ...
- 【MyBatis学习15】MyBatis的逆向工程生成代码
1. 什么是逆向工程 mybatis的一个主要的特点就是需要程序员自己编写sql,那么如果表太多的话,难免会很麻烦,所以mybatis官方提供了一个逆向工程,可以针对单表自动生成mybatis执行所需 ...
- popupwindow从底部弹出
参考了网上的一些代码,自己写了个类,上代码 /** * Created by Lee on 2016/2/26. */ public class CameraPopupWindow { private ...
- 【Android 开发教程】动态添加Fragments
本章节翻译自<Beginning-Android-4-Application-Development>,如有翻译不当的地方,敬请指出. 原书购买地址http://www.amazon.co ...