bzoj千题计划243:bzoj2325: [ZJOI2011]道馆之战
http://www.lydsy.com/JudgeOnline/problem.php?id=2325
设线段树节点区间为[l,r]
每个节点维护sum[0/1][0/1] 从l的A/B区域到r的A/B区域 经过冰块的最大数量
mx[0][0] 从l的A区域出发向r经过冰块的最大数量
mx[0][1] 从l的B区域出发向r经过冰块的最大数量
mx[1][0] 从r的A区域出发向l经过冰块的最大数量
mx[1][1] 从r的B区域出发向l经过冰块的最大数量
#include<cstdio>
#include<iostream>
#include<algorithm> #define N 30001 using namespace std; int n; int front[N],nxt[N<<],to[N<<],tot; int fa[N],dep[N],siz[N];
int bl[N]; int id[N],dy[N],cnt; bool a[N][]; #define max(x,y) ((x)>(y) ? (x) : (y)) struct node
{
int sum[][];
int mx[][]; node()
{
for(int i=;i<;++i)
for(int j=;j<;++j)
sum[i][j]=mx[i][j]=;
} node operator + (node p) const
{
node k;
for(int i=;i<=;++i)
for(int j=;j<=;++j)
{
if(sum[i][] && p.sum[][j])
k.sum[i][j]=max(k.sum[i][j],sum[i][]+p.sum[][j]);
if(sum[i][] && p.sum[][j])
k.sum[i][j]=max(k.sum[i][j],sum[i][]+p.sum[][j]);
}
k.mx[][]=max(k.sum[][],k.sum[][]);
k.mx[][]=max(k.sum[][],k.sum[][]);
k.mx[][]=max(k.sum[][],k.sum[][]);
k.mx[][]=max(k.sum[][],k.sum[][]);
if(sum[][]) k.mx[][]=max(k.mx[][],sum[][]+p.mx[][]);
if(sum[][]) k.mx[][]=max(k.mx[][],sum[][]+p.mx[][]);
if(sum[][]) k.mx[][]=max(k.mx[][],sum[][]+p.mx[][]);
if(sum[][]) k.mx[][]=max(k.mx[][],sum[][]+p.mx[][]);
if(p.sum[][]) k.mx[][]=max(k.mx[][],mx[][]+p.sum[][]);
if(p.sum[][]) k.mx[][]=max(k.mx[][],mx[][]+p.sum[][]);
if(p.sum[][]) k.mx[][]=max(k.mx[][],mx[][]+p.sum[][]);
if(p.sum[][]) k.mx[][]=max(k.mx[][],mx[][]+p.sum[][]);
k.mx[][]=max(k.mx[][],mx[][]);
k.mx[][]=max(k.mx[][],mx[][]);
k.mx[][]=max(k.mx[][],p.mx[][]);
k.mx[][]=max(k.mx[][],p.mx[][]);
return k;
} void turn()
{
swap(sum[][],sum[][]);
swap(mx[][],mx[][]);
swap(mx[][],mx[][]);
} }tr[N<<]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
} void dfs1(int x)
{
siz[x]=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x])
{
fa[to[i]]=x;
dep[to[i]]=dep[x]+;
dfs1(to[i]);
siz[x]+=siz[to[i]];
}
} void dfs2(int x,int top)
{
bl[x]=top;
id[x]=++cnt;
dy[cnt]=x;
int y=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x] && siz[to[i]]>siz[y]) y=to[i];
if(y) dfs2(y,top);
else return;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=y && to[i]!=fa[x]) dfs2(to[i],to[i]);
} void build(int k,int l,int r)
{
if(l==r)
{
if(a[dy[l]][]) tr[k].sum[][]=;
if(a[dy[l]][]) tr[k].sum[][]=;
if(a[dy[l]][] && a[dy[l]][]) tr[k].sum[][]=tr[k].sum[][]=;
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
return;
}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
tr[k]=tr[k<<]+tr[k<<|];
} node query(int k,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr) return tr[k];
int mid=l+r>>;
if(opr<=mid) return query(k<<,l,mid,opl,opr);
else if(opl>mid) return query(k<<|,mid+,r,opl,opr);
else return query(k<<,l,mid,opl,opr)+query(k<<|,mid+,r,opl,opr);
} void Query(int u,int v)
{
node ansu,ansv;
bool firstu=false,firstv=false;
while(bl[u]!=bl[v])
{
if(dep[bl[u]]>dep[bl[v]])
{
if(!firstu) firstu=true,ansu=query(,,n,id[bl[u]],id[u]);
else ansu=query(,,n,id[bl[u]],id[u])+ansu;
u=fa[bl[u]];
}
else
{
if(!firstv) firstv=true,ansv=query(,,n,id[bl[v]],id[v]);
else ansv=query(,,n,id[bl[v]],id[v])+ansv;
v=fa[bl[v]];
}
}
if(dep[u]>dep[v])
{
if(!firstu) firstu=true,ansu=query(,,n,id[v],id[u]);
else ansu=query(,,n,id[v],id[u])+ansu;
}
else
{
if(!firstv) firstv=true,ansv=query(,,n,id[u],id[v]);
else ansv=query(,,n,id[u],id[v])+ansv;
}
if(!firstu) ansu=ansv;
else
{
ansu.turn();
if(firstv) ansu=ansu+ansv;
}
cout<<max(ansu.mx[][],ansu.mx[][])<<'\n';
} void change(int k,int l,int r,int x,bool u,bool v)
{
if(l==r)
{
a[l][]=u;
a[l][]=v;
if(a[l][]) tr[k].sum[][]=;
else tr[k].sum[][]=;
if(a[l][]) tr[k].sum[][]=;
else tr[k].sum[][]=;
if(a[l][] && a[l][]) tr[k].sum[][]=tr[k].sum[][]=;
else tr[k].sum[][]=tr[k].sum[][]=;
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
return;
}
int mid=l+r>>;
if(x<=mid) change(k<<,l,mid,x,u,v);
else change(k<<|,mid+,r,x,u,v);
tr[k]=tr[k<<]+tr[k<<|];
} int main()
{
freopen("fight.in","r",stdin);
freopen("fight.out","w",stdout);
int m;
read(n); read(m);
int u,v;
for(int i=;i<n;++i)
{
read(u); read(v);
add(u,v);
}
dfs1();
dfs2(,);
char s[];
for(int i=;i<=n;++i)
{
scanf("%s",s);
if(s[]=='.') a[i][]=true;
if(s[]=='.') a[i][]=true;
}
build(,,n);
char c[];
while(m--)
{
scanf("%s",c);
if(c[]=='Q')
{
read(u); read(v);
Query(u,v);
}
else
{
read(u);
scanf("%s",c);
change(,,n,id[u],c[]=='.',c[]=='.');
}
}
}
bzoj千题计划243:bzoj2325: [ZJOI2011]道馆之战的更多相关文章
- bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块
http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...
- bzoj千题计划139:bzoj2229: [Zjoi2011]最小割
http://www.lydsy.com/JudgeOnline/problem.php?id=2229 最小割树介绍:http://blog.csdn.net/jyxjyx27/article/de ...
- bzoj千题计划196:bzoj4826: [Hnoi2017]影魔
http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...
- bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪
http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...
- bzoj千题计划177:bzoj1858: [Scoi2010]序列操作
http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...
- bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)
https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...
- bzoj千题计划304:bzoj3676: [Apio2014]回文串(回文自动机)
https://www.lydsy.com/JudgeOnline/problem.php?id=3676 回文自动机模板题 4年前的APIO如今竟沦为模板,,,╮(╯▽╰)╭,唉 #include& ...
- bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹
http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len ...
- bzoj千题计划278:bzoj4590: [Shoi2015]自动刷题机
http://www.lydsy.com/JudgeOnline/problem.php?id=4590 二分 这么道水题 没long long WA了两发,没判-1WA了一发,二分写错WA了一发 最 ...
随机推荐
- [BZOJ2326] [HNOI2011] 数学作业 (矩阵乘法)
Description Input Output Sample Input Sample Output HINT Source Solution 递推式长这样:$f[n]=f[n-1]*10^k+n$ ...
- MSIL实用指南-IL版hello world
我们学习编程开始时,一般用输出"hello world"的一段程序. C#版的"hello world"是 using System; namespace L0 ...
- WORD分栏后左右都能编辑
操作如下: 如果是office的请参照:https://zhidao.baidu.com/question/403577041.html 如果是WPS:1.点击插入,有一个分页,点击之后下面有一个可选 ...
- java 关键字final static native详解
java 关键字native static final详解 一.final 根据程序上下文环境,Java关键字final有"这是无法改变的"或者"终态的"含义, ...
- uwsgi服务启动(start)停止(stop)重新装载(reload)
1. 添加uwsgi相关文件 在之前的文章跟讲到过centos中搭建nginx+uwsgi+flask运行环境,本节就基于那一次的配置进行说明. 在www中创建uwsgi文件夹,用来存放uwsgi相关 ...
- java--Object类接受任意引用数据类型对象
java学习进展到类,首先就对万类之父Object类进行举例练习,这里我是对一维数组和接口用Object接受数组和接口. package test1; public class enum1 { pub ...
- handsontable自定义渲染
本文主要介绍在使用Handsontable过程中,对加载的数据进行字体颜色.样式(style).数据格式化,对齐方式的处理,并添加自定义图片和单机事件功能. 代码如下: <!DOCTYPE ht ...
- openflow 和 sdn (软件定义网络) 原理和教程
OpenFlow概述 OpenFlow简介 通俗的讲,OpenFlow是使用类似于API进程配置网络交换机的协议.OpenFlow的思路很简单,网络设备维护一个FlowTable并且只按照FlowTa ...
- SparkHiveContext和直接Spark读取hdfs上文件然后再分析效果区别
最近用spark在集群上验证一个算法的问题,数据量大概是一天P级的,使用hiveContext查询之后再调用算法进行读取效果很慢,大概需要二十多个小时,一个查询将近半个小时,代码大概如下: try: ...
- java反射使用及性能比较
环境准备 package com.lilei.pack09; public class Logger { public void show(){ System.out.println("he ...