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 ...
随机推荐
- LeetCode1090. 受标签影响的最大值
问题: 我们有一个项的集合,其中第 i 项的值为 values[i],标签为 labels[i]. 我们从这些项中选出一个子集 S,这样一来: |S| <= num_wanted 对于任意的标签 ...
- day24 02 单继承(派生)
day24 02 单继承(派生) 1.首先来看一个简单的例子 比如: 狗类的属性有:吃,喝,看门 鸟类的属性有:吃,喝,下蛋 看门和下蛋就是这两种动物不同的属性,而吃喝是两个共同的属性 以下代码实现了 ...
- BFS:UVa1590-IP Networks (子网掩码相关知识)
IP Networks Alex is administrator of IP networks. His clients have a bunch of individual IP addresse ...
- poj 3669 火星撞地球问题 bfs算法
题意:火星撞地球,你要跑到一个永远安全的地方,求最短时间 思路:bfs+预处理 这题的数据量比较大,所以需要进行预处理 对每个位置设上时间(被撞的最早时间) 未被撞的设为-1 for (int j = ...
- loj2032 「SDOI2016」游戏
做了 [JSOI2008]Blue Mary开公司 以后发现这 tm 不就是个傻逼树剖+李超线段树吗,做了以后发现我才是傻逼--树剖竟然写错了--这题是我目前写过最长的代码了qwq #include ...
- loj2000 「SDOI2017」数字表格
there #include <iostream> #include <cstring> #include <cstdio> using namespace std ...
- Clickonce - Change deployment URL after publish
mage.exe -Update C:\inetpub\wwwroot\aspnet40\AminoScience\Uploads\Application Files\AccUFeed_1_0_0_5 ...
- Leetcode34--->Search for a Range(在排序数组中找出给定值出现的范围)
题目:给定一个排序数组,找出给定的target值出现的范围:算法复杂度要求在O(logn);如果没有找到,则返回[-1, -1]; 举例: For example,Given [5, 7, 7, 8, ...
- [python IO学习篇] 补充.py文件是中文, .ini文件内容是中文
python 代码文件的编码.py文件默认是ASCII编码,中文在显示时会做一个ASCII到系统默认编码的转换,这时就会出错:SyntaxError: Non-ASCII character.需要在代 ...
- 解压文件夹python
# _*_ coding: utf-8 _*_ import zipfile import shutil import os print os.getcwd() basedir = os.path.d ...