POJ-3237:Tree(树链剖分)
来源:互联网 发布:单片机与上位机通信 编辑:程序博客网 时间:2024/06/04 17:49
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 vChange the weight of the ith edge to vNEGATE
a bNegate the weight of every edge on the path from a to bQUERY
a bFind the maximum weight of edges on the path from a to bInput
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 ≤ 10,000). The next N − 1 lines each contains three integers a, b and c, describing an edge connecting nodes a and bwith 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
131 2 12 3 2QUERY 1 2CHANGE 1 3QUERY 1 2DONE
Sample Output
13
思路:树链剖分。
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<iostream>using namespace std;const int MAX=2e5;struct edg{int x,y,z;}edg[MAX];vector<int>e[MAX];struct lenka{ int l,r; int ma;}A[MAX<<2];int d[MAX],son[MAX],fa[MAX],siz[MAX],top[MAX],val[MAX],num[MAX],all;void build(int k,int l,int r){ A[k].l=l,A[k].r=r; if(l==r){A[k].ma=val[l];return;} build(2*k,l,(l+r)/2); build(2*k+1,(l+r)/2+1,r); A[k].ma=max(A[2*k].ma,A[2*k+1].ma);}void negat(int k,int x,int y){ if(A[k].l==A[k].r){A[k].ma*=-1;return;} if(y<=A[2*k].r)negat(2*k,x,y); else if(x>=A[2*k+1].l)negat(2*k+1,x,y); else { negat(2*k,x,A[2*k].r); negat(2*k+1,A[2*k+1].l,y); } A[k].ma=max(A[2*k].ma,A[2*k+1].ma);}void change(int k,int x,int y){ if(x==A[k].l&&x==A[k].r){A[k].ma=y;return;} if(x<=A[2*k].r)change(2*k,x,y); else change(2*k+1,x,y); A[k].ma=max(A[2*k].ma,A[2*k+1].ma);}int ask(int k,int x,int y){ if(x==A[k].l&&y==A[k].r)return A[k].ma; if(y<=A[2*k].r)return ask(2*k,x,y); else if(x>=A[2*k+1].l)return ask(2*k+1,x,y); return max(ask(2*k,x,A[2*k].r),ask(2*k+1,A[2*k+1].l,y));}void dfs1(int k,int f,int dep){ d[k]=dep; siz[k]=1; son[k]=0; fa[k]=f; for(int i=0;i<e[k].size();i++) { int nex=e[k][i]; if(nex==f)continue; dfs1(nex,k,dep+1); siz[k]+=siz[nex]; if(siz[son[k]]<siz[nex])son[k]=nex; }}void dfs2(int k,int tp){ top[k]=tp; num[k]=++all; if(son[k])dfs2(son[k],tp); for(int i=0;i<e[k].size();i++) { if(e[k][i]==fa[k]||e[k][i]==son[k])continue; dfs2(e[k][i],e[k][i]); }}int QWQ(int x,int y){ int tpx=top[x],tpy=top[y],ans=-(1<<30);//数据范围不知道,一开始设的为0,一直WA while(tpx!=tpy) { if(d[tpx]<d[tpy]) { swap(tpx,tpy); swap(x,y); } ans=max(ans,ask(1,num[tpx],num[x])); x=fa[tpx]; tpx=top[x]; } if(x==y)return ans; if(d[x]>d[y])swap(x,y); return max(ans,ask(1,num[son[x]],num[y]));}void QAQ(int x,int y){ int tpx=top[x],tpy=top[y]; while(tpx!=tpy) { if(d[tpx]<d[tpy]) { swap(tpx,tpy); swap(x,y); } negat(1,num[tpx],num[x]); x=fa[tpx]; tpx=top[x]; } if(x==y)return; if(d[x]>d[y])swap(x,y); negat(1,num[son[x]],num[y]);}int main(){ int T,n;cin>>T; while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++)e[i].clear(); memset(siz,0,sizeof siz); memset(d,0,sizeof d); memset(son,0,sizeof son); for(int i=1;i<n;i++) { scanf("%d%d%d",&edg[i].x,&edg[i].y,&edg[i].z); e[edg[i].x].push_back(edg[i].y); e[edg[i].y].push_back(edg[i].x); } all=0; dfs1(1,0,1); dfs2(1,1); for(int i=1;i<n;i++) { if(d[edg[i].x]<d[edg[i].y])swap(edg[i].x,edg[i].y); val[num[edg[i].x]]=edg[i].z; } build(1,1,all); char op[20]; while(scanf("%s",op)!=EOF&&strcmp(op,"DONE")!=0) { int x,y; scanf("%d%d",&x,&y); if(strcmp(op,"QUERY")==0)printf("%d\n",QWQ(x,y)); else if(strcmp(op,"CHANGE")==0)change(1,num[edg[x].x],y); else QAQ(x,y); } } return 0;}
- poj 3237 Tree(树链剖分)
- POJ 3237 Tree (树链剖分)
- POJ 3237 Tree(树链剖分)
- POJ 3237 Tree (树链剖分)
- poj 3237 Tree(树链剖分)
- POJ-3237:Tree(树链剖分)
- POJ 3237 Tree 树链剖分
- 【POJ】3237 Tree 树链剖分
- POJ 3237 Tree 树链剖分
- 【树链剖分】 POJ 3237 Tree
- poj 3237 Tree(树链剖分)
- POJ 3237 Tree (树链剖分)
- POJ 3237 Tree 树链剖分
- POJ 3237 Tree 树链剖分
- poj 3237 Tree 树链剖分
- poj 3237 Tree 树链剖分
- POJ 3237 - Tree(树链剖分)
- poj 3237 Tree 树链剖分
- map的三种遍历方式
- input checkbox勾选怎么点击去掉勾
- 2017.11.23
- ACM-11月23日周四周中训练心得
- python之join和split
- POJ-3237:Tree(树链剖分)
- 零和博弈下的逆增强学习
- C++ IO类(2) 流的缓冲
- tcp/ip学习笔记--第18章TCP Establishment and termination
- Tomcat学习
- java多线程(16)--线程控制之线程优先级
- Spring技术内幕2
- 关于指针与数组的相关例题详解
- leetCode-Maximum Product of Three Numbers