375. Query on a tree
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "QUERY" operation, write one integer representing its result.
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
树链剖分边权、= =
这题告诉我、宏定义可能导致超时、姿势不对可能导致超时
#include <iostream> #include <algorithm> #include <cstdio> #include <queue> #include <cmath> #include <map> #include <iterator> #include <cstring> #include <string> using namespace std; #pragma comment(linker, "/STACK:1024000000,1024000000") //手动加栈、windows系统容易爆栈 #define INF 0x7fffffff #define ll long long #define N 50005 struct Edge2 { int a,b,c; }s[N<<1]; struct Edge { int to,next; }edge[N<<1]; int head[N],tot; int num[N]; int pos; int fa[N]; int son[N]; int p[N]; int fp[N]; int deep[N]; int size[N]; int top[N]; int n; void init() { tot=0; pos=1; memset(head,-1,sizeof(head)); memset(son,-1,sizeof(son)); } void add(int x,int y) { edge[tot].to=y; edge[tot].next=head[x]; head[x]=tot++; } void dfs1(int now,int pre,int d) { deep[now]=d; fa[now]=pre; size[now]=1; for(int i=head[now];i!=-1;i=edge[i].next) { int next=edge[i].to; if(next!=pre) { dfs1(next,now,d+1); size[now]+=size[next]; if(son[now]==-1 || size[next]>size[son[now]]) { son[now]=next; } } } } void dfs2(int now,int tp) { top[now]=tp; p[now]=pos++; fp[p[now]]=now; if(son[now]==-1) return; dfs2(son[now],tp); for(int i=head[now];i!=-1;i=edge[i].next) { int next=edge[i].to; if(next!=son[now]&&next!=fa[now]) { dfs2(next,next); } } } /* 线段树、单点更新 */ int mx[N<<2]; void pushup(int rt) { mx[rt]=max(mx[rt<<1],mx[rt<<1|1]); } void build(int l,int r,int rt) { if(l==r) { mx[rt]=num[fp[l]]; return; } int m=(l+r)>>1; build(l,m,rt<<1); build(m+1,r,rt<<1|1); pushup(rt); } void update(int l,int r,int rt,int pos,int val) { if(l==r) { mx[rt]=val; return; } int m=(l+r)>>1; if(pos<=m) update(l,m,rt<<1,pos,val); else update(m+1,r,rt<<1|1,pos,val); pushup(rt); } int query(int l,int r,int rt,int L,int R) { if(L<=l && R>=r) { return mx[rt]; } int m=(l+r)>>1; int res=-1; if(L<=m) res=max(res,query(l,m,rt<<1,L,R)); if(R>m) res=max(res,query(m+1,r,rt<<1|1,L,R)); return res; /* 这样超时、不明就里、看出来的大神请指导。。。 if(l==L && r==R) { return mx[rt]; } int m=(l+r)>>1; if(L>m) return query(m+1,r,rt<<1|1,L,R); else if(R<=m) return query(l,m,rt<<1,L,R); else return max(query(l,m,rt<<1,L,m),query(m+1,r,rt<<1|1,m+1,R)); */ } int convert(int pos) { int a=s[pos].a; int b=s[pos].b; if(deep[a]>deep[b]) return a; return b; } void pre_solve() { memset(num,-1,sizeof(num)); for(int i=1;i<n;i++) { num[convert(i)]=s[i].c; } } int change(int x,int y) { int ans=-INF; int f1=top[x]; int f2=top[y]; while(f1!=f2) { if(deep[f1]<deep[f2]) { swap(x,y); swap(f1,f2); } ans=max(ans,query(1,n,1,p[f1],p[x])); x=fa[f1]; f1=top[x]; } if(deep[x]>deep[y]) swap(x,y); ans=max(ans,query(1,n,1,p[x]+1,p[y])); return ans; } int main() { int T; scanf("%d",&T); while(T--) { init(); scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d%d",&s[i].a,&s[i].b,&s[i].c); add(s[i].a,s[i].b); add(s[i].b,s[i].a); } dfs1(1,0,0); dfs2(1,1); pre_solve(); build(1,n,1); while(1) { char op[10]; scanf("%s",op); if(op[0]=='D') break; else if(op[0]=='C') { int a,b; scanf("%d%d",&a,&b); a=convert(a); update(1,n,1,p[a],b); } else { int a,b; scanf("%d%d",&a,&b); printf("%d\n",change(a,b)); } } } return 0; }