标签:can namespace -- include using char ++ lse names
LCA真香
(dep为初始化,3秒挂)
第一问:经典树上差分
第二问:分两类
1.第k个点为u的父亲 直接跳
2.转换一下再跳
代码:
#include<bits/stdc++.h> using namespace std; const int N=10005; int T; int n; int hed[N<<1],tal[N<<1],val[N<<1],nxt[N<<1],cnt=0; int f[N][30]; int dep[N]; int w[N][30]; char s[30]; int A,B,C; void addege(int x,int y,int z){ cnt++; tal[cnt]=y; val[cnt]=z; nxt[cnt]=hed[x]; hed[x]=cnt; } void dfs(int u,int fa){ f[u][0]=fa; for(int i=hed[u];i;i=nxt[i]){ int v=tal[i]; if(v==fa) continue; dep[v]=dep[u]+1; w[v][0]=val[i]; dfs(v,u); } } int jump(int x,int k){ for(int i=20;i>=0;i--){ if(k>=(1<<i)+1){ x=f[x][i]; k-=(1<<i); } } return x; } int lca(int x,int y){ if(dep[x]<dep[y]) swap(x,y); for(int i=20;i>=0;i--) if(dep[f[x][i]]>=dep[y]) x=f[x][i]; if(x==y) return x; for(int i=20;i>=0;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; return f[x][0]; } int lca1(int x,int y){ int sum=0; if(dep[x]<dep[y]) swap(x,y); for(int i=20;i>=0;i--) if(dep[f[x][i]]>=dep[y]) sum+=w[x][i],x=f[x][i]; if(x==y) return sum; for(int i=20;i>=0;i--) if(f[x][i]!=f[y][i]) sum+=w[x][i],sum+=w[y][i],x=f[x][i],y=f[y][i]; sum+=w[x][0],sum+=w[y][0]; return sum; } int lca2(int x,int y,int k){ int LCA=lca(x,y); if(dep[x]-dep[LCA]+1<=k){ k=dep[x]+dep[y]-(dep[LCA]*2)+2-k; x=y; } return jump(x,k); } int main(){ cin>>T; while(T--){ cnt=0; memset(w,0,sizeof(w)); memset(dep,0,sizeof(dep)); memset(f,0,sizeof(f)); memset(hed,0,sizeof(hed)); scanf("%d",&n); for(int i=1;i<n;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); addege(x,y,z); addege(y,x,z); } dep[1]=1; dfs(1,1); for(int j=1;j<=20;j++){ for(int i=1;i<=n;i++){ f[i][j]=f[f[i][j-1]][j-1]; w[i][j]=w[i][j-1]+w[f[i][j-1]][j-1]; } } while(1){ scanf("%s",s); if(s[1]==‘O‘){ break; } else if(s[1]==‘I‘){ scanf("%d%d",&A,&B); printf("%d\n",lca1(A,B)); } else if(s[1]==‘T‘){ scanf("%d%d%d",&A,&B,&C); printf("%d\n",lca2(A,B,C)); } } } return 0; }
SP913 QTREE2 - Query on a tree II
标签:can namespace -- include using char ++ lse names
原文地址:https://www.cnblogs.com/QYJ060604/p/11710623.html