BZOJ - 2157 树链剖分+线段树
/*H E A D*/
int from[maxn<<1],to[maxn<<1],nxt[maxn<<1],cost[maxn<<1],head[maxn],tot;
int size[maxn],fa[maxn],depth[maxn],top[maxn],son[maxn],dfn[maxn],pre[maxn],tot2;
void init(){
memset(head,-1,sizeof head);
memset(son,0,sizeof son);
memset(size,0,sizeof size);
memset(fa,0,sizeof fa);
tot=tot2=0;
}
void add(int u,int v,int w=0){
from[tot]=u;to[tot]=v;nxt[tot]=head[u];cost[tot]=w;
head[u]=tot++;
swap(u,v);
from[tot]=u;to[tot]=v;nxt[tot]=head[u];cost[tot]=w;
head[u]=tot++;
}
void dfs(int u,int p,int d){
size[u]=1;fa[u]=p;depth[u]=d;
erep(i,u){
int v=to[i];
if(v==p)continue;
dfs(v,u,d+1);
size[u]+=size[v];
if(size[v]>size[son[u]]){//update
son[u]=v;
}
}
}
void dfs2(int u,int tp){
pre[++tot2]=u;
dfn[u]=tot2;
top[u]=tp;
if(son[u]) dfs2(son[u],tp);//heavy --- ori top
erep(i,u){
int v=to[i];
if(v==son[u]||v==fa[u])continue;
dfs2(v,v);//light --- themselves
}
}
int val[maxn<<2];
struct ST{
int sum[maxn<<2],mx[maxn<<2],mn[maxn<<2];
bool rev[maxn<<2];
#define lc o<<1
#define rc o<<1|1
void pu(int o){
sum[o]=sum[lc]+sum[rc];
mx[o]=max(mx[lc],mx[rc]);
mn[o]=min(mn[lc],mn[rc]);
}
void pd(int o){
if(rev[o]){
sum[lc]=-sum[lc];mx[lc]=-mx[lc];mn[lc]=-mn[lc];
swap(mx[lc],mn[lc]);
sum[rc]=-sum[rc];mx[rc]=-mx[rc];mn[rc]=-mn[rc];
swap(mx[rc],mn[rc]);
rev[lc]^=1;
rev[rc]^=1;
rev[o]=0;
}
}
void build(int o,int l,int r){
rev[o]=0;mx[o]=-oo;mn[o]=oo;
if(l==r){
sum[o]=mx[o]=mn[o]=val[pre[l]];//note
return;
}
int m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
pu(o);
}
void update(int o,int l,int r,int k,int v){
if(l==r){
sum[o]=mx[o]=mn[o]=v;
return;
}
pd(o);
int m=l+r>>1;
if(k<=m) update(lc,l,m,k,v);
else update(rc,m+1,r,k,v);
pu(o);
}
void flip(int o,int l,int r,int L,int R){
if(L<=l&&r<=R){
rev[o]^=1;
sum[o]=-sum[o];
mx[o]=-mx[o];
mn[o]=-mn[o];
swap(mx[o],mn[o]);
return;
}
pd(o);
int m=l+r>>1;
if(L<=m) flip(lc,l,m,L,R);
if(R>m) flip(rc,m+1,r,L,R);
pu(o);
}
int query(int o,int l,int r,int L,int R,int op){
if(L<=l&&r<=R){
switch(op){
case 1: return sum[o];
case 2: return mx[o];
case 3: return mn[o];
}
}
pd(o);
int m=l+r>>1;
int ans;
if(op==1){
ans=0;
if(L<=m) ans+=query(lc,l,m,L,R,op);
if(R>m) ans+=query(rc,m+1,r,L,R,op);
}
else if(op==2){
ans=-oo;
if(L<=m) ans=max(query(lc,l,m,L,R,op),ans);
if(R>m) ans=max(query(rc,m+1,r,L,R,op),ans);
}
else{
ans=oo;
if(L<=m) ans=min(query(lc,l,m,L,R,op),ans);
if(R>m) ans=min(query(rc,m+1,r,L,R,op),ans);
}
return ans;
}
}st;
char str[555];
void solve(){
int l,r,p1,p2,sum=0,mx=-oo,mn=oo;
l=read();r=read();l++;r++;
p1=top[l];p2=top[r];
while(p1!=p2){
if(depth[p1]<depth[p2]){
swap(p1,p2);
swap(l,r);
}
if(str[0]=='N') st.flip(1,1,tot2,dfn[p1],dfn[l]);
else if(str[0]=='S') sum+=st.query(1,1,tot2,dfn[p1],dfn[l],1);
else if(str[1]=='I') mn=min(mn,st.query(1,1,tot2,dfn[p1],dfn[l],3));
else if(str[1]=='A') mx=max(mx,st.query(1,1,tot2,dfn[p1],dfn[l],2));
l=fa[p1];
p1=top[l];
}
if(depth[l]>depth[r]) swap(l,r);
if(l==r){
// if(str[0]=='N') st.flip(1,1,tot2,dfn[l],dfn[r]); //!WrongAnswer
if(str[0]=='S') println(sum);
else if(str[1]=='I') println(mn);
else if(str[1]=='A') println(mx);
}
else{
l=son[l];
if(str[0]=='N'){
st.flip(1,1,tot2,dfn[l],dfn[r]);
}
else if(str[0]=='S'){
sum+=st.query(1,1,tot2,dfn[l],dfn[r],1);
println(sum);
}
else if(str[1]=='I'){
mn=min(mn,st.query(1,1,tot2,dfn[l],dfn[r],3));
println(mn);
}
else if(str[1]=='A'){
mx=max(mx,st.query(1,1,tot2,dfn[l],dfn[r],2));
println(mx);
}
}
}
int main(){
int n,u,v,w,x,y;
while(~iin(n)){
init();
rep(i,1,n-1){
u=read();v=read();w=read();
u++;v++;
add(u,v,w);
}
dfs(1,0,1);
dfs2(1,1);
rep(i,0,tot-1){
if(depth[from[i]]>depth[to[i]]){//
swap(from[i],to[i]);
}
val[to[i]]=cost[i];
}
st.build(1,1,tot2);
int m=read();
rep(i,1,m){
s0(str);
if(str[0]=='C'){
x=read();y=read();
st.update(1,1,tot2,dfn[to[(x-1)<<1]],y);//note bridgeNum->edgeNum
}
else solve();
}
}
return 0;
}
BZOJ - 2157 树链剖分+线段树的更多相关文章
- bzoj 2157: 旅游【树链剖分+线段树】
裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...
- BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)
前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...
- bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2852 Solved: 1668[Submit][Sta ...
- BZOJ 3589 动态树 (树链剖分+线段树)
前言 众所周知,90%90\%90%的题目与解法毫无关系. 题意 有一棵有根树,两种操作.一种是子树内每一个点的权值加上一个同一个数,另一种是查询多条路径的并的点权之和. 分析 很容易看出是树链剖分+ ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
随机推荐
- c语言实践 打印三角形
效果如下: 我是怎么考虑这个问题的. 首先共有5行,那么我们需要一个循环,让这个循环走5遍. 那么我们有个大概的代码结构 for(int i=0;i<5;i++) { } i的定义域是[0,4] ...
- 利用Thread.stop完成方法执行超时中断
示例代码可以从github上获取 https://github.com/git-simm/simm-framework.git 接上篇博客<FutureTask子线程取消执行的状态判断> ...
- Linux基础-工作中经常使用到的linux 命令
linux 常用命令 (1)命令ls——列出文件 ls -la 给出当前目录下所有文件的一个长列表,包括以句点开头的“隐藏”文件 ls a* 列出当前目录下以字母a开头的所有文件 ls -l *.d ...
- (转)XSS危害——session劫持
原文地址:http://www.cnblogs.com/dolphinX/p/3403027.html 在跨站脚本攻击XSS中简单介绍了XSS的原理及一个利用XSS盗取存在cookie中用户名和密码的 ...
- ajax 跨域名调用
在ajax 中要跨域名 请求的时候要注意 1. dataType: 'jsonp', 2. jsonp: 'callback', <script type="text/javascri ...
- hibernate的获取session的两方法比较,和通过id获取对象的比较,一级缓存二级缓存
opensession与currentsession的联系与区别 在同一个线程中opensession的session是不一样的,而currentsession获取的session是一样的,这就保证了 ...
- javaScript入门之常用事件
JS中的常用事件 onfocus/onblur:聚焦离焦事件,用于表单校验的时候比较合适. onclick/ondblclick:鼠标单击和双击事件 onkeydown/onkeypress:搜索引擎 ...
- C#@的用法
string path = @"C:\Windows\"; // 如果不加 @,编译会提示无法识别的转义序列 // 如果不加 @,可以写成如下 string path2 = &qu ...
- System.Net.Http
System.Net.Http DotNet菜园 占个位置^-^ 2018-11-10 09:55:00修改 这个HttpClient的学习笔记一直迟迟未记录,只引用了其他博主的博客链接占个位置,但被 ...
- ASP.NET Core依赖注入最佳实践,提示&技巧
分享翻译一篇Abp框架作者(Halil İbrahim Kalkan)关于ASP.NET Core依赖注入的博文. 在本文中,我将分享我在ASP.NET Core应用程序中使用依赖注入的经验和建议. ...