Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 10785 | Accepted: 2800 |
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 ≤ 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
1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE
Sample Output
1 3
思路:树链剖分。
#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;
}
来源:CSDN
作者:Mitsuha_
链接:https://blog.csdn.net/Mitsuha_/article/details/78620112