AC日记——Tree poj 3237
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 9233 | Accepted: 2431 |
Description
You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms:
CHANGE i v |
Change the weight of the ith edge to v |
NEGATE a b |
Negate the weight of every edge on the path from a to b |
QUERY a b |
Find the maximum weight of edges on the path from a to b |
Input
The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases.
Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 100,000). The next N − 1 lines each contains three integers a, b and c, describing an edge connecting nodes a and b with weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE
” ends the test case.
Output
For each “QUERY
” instruction, output the result on a separate line.
Sample Input
1 3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE
Sample Output
1
3
Source
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> #define maxn 1000005 using namespace std; struct TreeNodeType {
int l,r,dis,dis_,mid,flag;
};
struct TreeNodeType tree[maxn<<]; struct EdgeType {
int v,w,next;
};
struct EdgeType edge[maxn<<]; int u_[maxn],v_[maxn];
int if_z,t,n,cnt,head[maxn],deep[maxn],f[maxn];
int flag[maxn],top[maxn],size[maxn],dis[maxn],dis_[maxn]; char Cget; inline void in(int &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
} inline void edge_add(int u,int v,int w)
{
edge[++cnt].v=v,edge[cnt].w=w,edge[cnt].next=head[u],head[u]=cnt;
edge[++cnt].v=u,edge[cnt].w=w,edge[cnt].next=head[v],head[v]=cnt;
} void search_1(int now,int fa)
{
int pos=cnt++;
deep[now]=deep[fa]+,f[now]=fa;
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].v==fa) continue;
dis_[edge[i].v]=edge[i].w;
search_1(edge[i].v,now);
}
size[now]=cnt-pos;
} void search_2(int now,int chain)
{
int pos=;
top[now]=chain;
flag[now]=++cnt;
dis[flag[now]]=dis_[now];
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].v==f[now]) continue;
if(size[edge[i].v]>size[pos]) pos=edge[i].v;
}
if(pos==) return ;
search_2(pos,chain);
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].v==f[now]||edge[i].v==pos) continue;
search_2(edge[i].v,edge[i].v);
}
} inline void tree_up(int now)
{
tree[now].dis=max(tree[now<<].dis,tree[now<<|].dis);
tree[now].dis_=min(tree[now<<].dis_,tree[now<<|].dis_);
} inline void tree_down(int now)
{
if(tree[now].l==tree[now].r) return ;
tree[now<<].dis*=-,tree[now<<|].dis*=-;
tree[now<<].dis_*=-,tree[now<<|].dis_*=-;
tree[now<<].flag*=-,tree[now<<|].flag*=-;
swap(tree[now<<].dis_,tree[now<<].dis);
swap(tree[now<<|].dis_,tree[now<<|].dis);
tree[now].flag=;return ;
} void tree_build(int now,int l,int r)
{
tree[now].l=l,tree[now].r=r,tree[now].flag=;
if(l==r)
{
tree[now].dis=dis[l];
tree[now].dis_=tree[now].dis;
return ;
}
tree[now].mid=(l+r)>>;
tree_build(now<<,l,tree[now].mid);
tree_build(now<<|,tree[now].mid+,r);
tree_up(now);
} void tree_change(int now,int to,int x)
{
if(tree[now].l==tree[now].r)
{
tree[now].dis=x;
tree[now].dis_=x;
return ;
}
if(tree[now].flag==-) tree_down(now);
if(to<=tree[now].mid) tree_change(now<<,to,x);
else tree_change(now<<|,to,x);
tree_up(now);
} void tree_negate(int now,int l,int r)
{
if(tree[now].l==l&&tree[now].r==r)
{
tree[now].dis*=-;
tree[now].dis_*=-;
swap(tree[now].dis,tree[now].dis_);
tree[now].flag*=-;
return ;
}
if(tree[now].flag==-) tree_down(now);
if(l>tree[now].mid) tree_negate(now<<|,l,r);
else if(r<=tree[now].mid) tree_negate(now<<,l,r);
else
{
tree_negate(now<<,l,tree[now].mid);
tree_negate(now<<|,tree[now].mid+,r);
}
tree_up(now);
} int tree_query(int now,int l,int r)
{
if(tree[now].l==l&&tree[now].r==r)
{
return tree[now].dis;
}
if(tree[now].flag==-) tree_down(now);
if(l>tree[now].mid) return tree_query(now<<|,l,r);
else if(r<=tree[now].mid) return tree_query(now<<,l,r);
else
{
return max(tree_query(now<<,l,tree[now].mid),tree_query(now<<|,tree[now].mid+,r));
}
} int solve_query(int x,int y)
{
int pos=-0x7ffffff;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
pos=max(pos,tree_query(,flag[top[x]],flag[x]));
x=f[top[x]];
}
if(x==y) return pos;
if(deep[x]>deep[y]) swap(x,y);
pos=max(pos,tree_query(,flag[x]+,flag[y]));
return pos;
} void solve_negate(int x,int y)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
tree_negate(,flag[top[x]],flag[x]);
x=f[top[x]];
}
if(x==y) return ;
if(deep[x]>deep[y]) swap(x,y);
tree_negate(,flag[x]+,flag[y]);
} int main()
{
in(t);
while(t--)
{
memset(head,,sizeof(head));
in(n);cnt=;
int u,v,w;char ch[];
for(int i=;i<n;i++)
{
in(u),in(v),in(w);
u_[i]=u,v_[i]=v,edge_add(u,v,w);
}
cnt=,search_1(,);
cnt=,search_2(,);
tree_build(,,n);
for(int i=;i<n;i++)
{
if(deep[u_[i]]<deep[v_[i]]) swap(u_[i],v_[i]);
}
while()
{
cin>>ch;
if(ch[]=='D') break;
in(u),in(v);
if(ch[]=='N') solve_negate(u,v);
if(ch[]=='C') tree_change(,flag[u_[u]],v);
if(ch[]=='Q')
{
cout<<solve_query(u,v);
putchar('\n');
}
}
}
return ;
}
AC日记——Tree poj 3237的更多相关文章
- AC日记——Crane poj 2991
POJ - 2991 思路: 向量旋转: 代码: #include <cmath> #include <cstdio> #include <cstring> #in ...
- AC日记——Dividing poj 1014
Dividing Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 69575 Accepted: 18138 Descri ...
- AC日记——pigs poj 1149
POJ - 1149 思路: 最大流: 代码: #include <cstdio> #include <cstring> #include <iostream> # ...
- AC日记——Dining poj 3281
[POJ-3281] 思路: 把牛拆点: s向食物连边,流量1: 饮料向t连边,流量1: 食物向牛1连边,流量1: 牛2向饮料连边,流量1: 最大流: 来,上代码: #include <cstd ...
- AC日记——Two poj 1849
Two 思路: 树形DP求直径: 答案是边权总和*2-直径: dp[i][1]::以i为根的子树中最长的路径: dp[i][0]::以i为根的子树中次长的路径: 来,上代码: #include < ...
- AC日记——Oulipo poj 3461
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37958 Accepted: 15282 Description The ...
- poj 3237 Tree [LCA] (树链剖分)
poj 3237 tree inline : 1. inline 定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高. 2. 很明显,类 ...
- poj 3237 Tree(树链拆分)
题目链接:poj 3237 Tree 题目大意:给定一棵树,三种操作: CHANGE i v:将i节点权值变为v NEGATE a b:将ab路径上全部节点的权值变为相反数 QUERY a b:查询a ...
- cogs 1583. [POJ 3237] 树的维护 树链剖分套线段树
1583. [POJ 3237] 树的维护 ★★★★ 输入文件:maintaintree.in 输出文件:maintaintree.out 简单对比时间限制:5 s 内存限制:128 ...
随机推荐
- LVS-nat模式-原理介绍
集群,为解决某个特定问题将多台计算机组合起来形成的单个系统 lvs-nat: 本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发 lvs集群类 ...
- VMware安装Ubuntu配置NAT模式下静态IP,解决访问外网问题
安装好VMware后,打开网络连接可以看到有VMware Network Adapter VMnet1和VMware Network Adapter VMnet8两个网络适配器,VMnet1是针对桥接 ...
- 【整理】虚拟机和主机ping不通解决办法,虚拟机ping不通外网的解决方法
检查几个方面: 1.检查虚拟网卡有没有被禁用2.检查虚拟机与物理机是否在一个VMNet中3.检查虚拟机的IP地址与物理机对应的VMNet是否在一个网段4.检查虚拟机与物理机的防火墙是否允许PING, ...
- Pytorch学习(一)—— 自动求导机制
现在对 CNN 有了一定的了解,同时在 GitHub 上找了几个 examples 来学习,对网络的搭建有了笼统地认识,但是发现有好多基础 pytorch 的知识需要补习,所以慢慢从官网 API进行学 ...
- HDU 5468 Puzzled Elena 莫比乌斯反演
题意: 给出一棵树,每个点上有权值.然后求每棵子树中与根节点互质( \(gcd(a, b) = 1\) )的节点个数. 分析: 对于一颗子树来说,设根节点的权值为\(u\), \(count_i\)表 ...
- 评估后Vista时代系统内核模式安全性
Windows Vista与之前的MS Windows版本(包括WindowsXPSP2)相比增加了很多的安全性.Vista新安全性的特征可以包括以下几个方面: 驱动签名 路径保护 内核模式代码完整性 ...
- react技术栈实践(1)
本文来自网易云社区 作者:汪洋 背景 最近开发一个全新AB测试平台,思考了下正好可以使用react技术开发. 实践前技术准备 首先遇到一个概念,redux.这货还真不好理解,大体的理解:Store包含 ...
- iphone使用keychain来存取用户名和密码
1.在arc下系统提示使用__bridge http://www.cnblogs.com/zzltjnh/p/3885012.html 参考文档:http://blog.csdn.net/jerr ...
- Clickonce - Change deployment URL after publish
mage.exe -Update C:\inetpub\wwwroot\aspnet40\AminoScience\Uploads\Application Files\AccUFeed_1_0_0_5 ...
- 微信小程序开发 -- 设置屏幕亮度
wx.setScreenBrightness(OBJECT) 设置屏幕亮度. OBJECT参数说明: 参数 类型 必填 说明 value Number 是 屏幕亮度值,范围 0~1,0 最暗,1 最亮 ...