Company CodeForces - 1062E
阿新 • • 發佈:2018-11-23
http://codeforces.com/problemset/problem/1062/E
[l,r]內決定lca的肯定是dfs序最小和最大的兩個點 因為一棵子樹的dfs序是連續的 線段樹維護一下每個點dfs序的最大次大和最小次小即可 看刪最小合適還是刪最大合適
比賽時水題切的太慢了 根本沒看見這個題 菜的一批
#include <bits/stdc++.h> using namespace std; const int maxn=1e5+10; const int N=0x3f3f3f3f; struct node { int v,next; }; node edge[2*maxn]; int dp[maxn][20]; int maxx[4*maxn],idmax[4*maxn],minn[4*maxn],idmin[4*maxn]; int first[maxn],deep[maxn],mp[maxn]; int n,q,num; void addedge(int u,int v) { edge[num].v=v; edge[num].next=first[u]; first[u]=num++; } void dfs(int cur,int fa) { int i,v; mp[cur]=++num; for(i=first[cur];i!=-1;i=edge[i].next){ v=edge[i].v; if(v!=fa){ dp[v][0]=cur,deep[v]=deep[cur]+1; dfs(v,cur); } } } void solve() { int i,j; dp[1][0]=0,deep[1]=0; dfs(1,0); for(j=1;(1<<j)<=n;j++){ for(i=1;i<=n;i++){ dp[i][j]=dp[dp[i][j-1]][j-1]; } } } int getlca(int u,int v) { int i; if(deep[u]<deep[v]) swap(u,v); for(i=log2(n);i>=0;i--){ if(deep[dp[u][i]]>=deep[v]) u=dp[u][i]; } if(u==v) return u; for(i=log2(n);i>=0;i--){ if(dp[u][i]!=dp[v][i]) u=dp[u][i],v=dp[v][i]; } return dp[u][0]; } void pushup(int cur) { if(maxx[2*cur]>maxx[2*cur+1]){ maxx[cur]=maxx[2*cur]; idmax[cur]=idmax[2*cur]; } else{ maxx[cur]=maxx[2*cur+1]; idmax[cur]=idmax[2*cur+1]; } if(minn[2*cur]<minn[2*cur+1]){ minn[cur]=minn[2*cur]; idmin[cur]=idmin[2*cur]; } else{ minn[cur]=minn[2*cur+1]; idmin[cur]=idmin[2*cur+1]; } } void build(int l,int r,int cur) { int m; if(l==r){ maxx[cur]=minn[cur]=mp[l]; idmax[cur]=idmin[cur]=l; return; } m=(l+r)/2; build(l,m,2*cur); build(m+1,r,2*cur+1); pushup(cur); } void update(int tar,int val,int l,int r,int cur) { int m; if(l==r){ maxx[cur]=minn[cur]=val; return; } m=(l+r)/2; if(tar<=m) update(tar,val,l,m,2*cur); else update(tar,val,m+1,r,2*cur+1); pushup(cur); } void query(int tp,int &res,int &val,int pl,int pr,int l,int r,int cur) { int m; if(pl<=l&&r<=pr){ if(tp==0){ if(val>minn[cur]){ val=minn[cur]; res=idmin[cur]; } } else{ if(val<maxx[cur]){ val=maxx[cur]; res=idmax[cur]; } } return; } m=(l+r)/2; if(pl<=m) query(tp,res,val,pl,pr,l,m,2*cur); if(pr>m) query(tp,res,val,pl,pr,m+1,r,2*cur+1); } int main() { int i,l,r,u,v,p,val,res,ans1,ans2; scanf("%d%d",&n,&q); memset(first,-1,sizeof(first)); num=0; for(i=2;i<=n;i++){ scanf("%d",&p); addedge(p,i),addedge(i,p); } num=0; solve(); build(1,n,1); while(q--){ scanf("%d%d",&l,&r); ans2=-1; val=N; query(0,u,val,l,r,1,n,1);//minn val=-N; query(1,p,val,l,r,1,n,1); update(p,-N,1,n,1); val=-N; query(1,v,val,l,r,1,n,1);//cmaxx update(p,mp[p],1,n,1); res=deep[getlca(u,v)]; if(ans2<res){ ans1=p,ans2=res; } val=-N; query(1,u,val,l,r,1,n,1);//maxx val=N; query(0,p,val,l,r,1,n,1); update(p,N,1,n,1); val=N; query(0,v,val,l,r,1,n,1);//cminn update(p,mp[p],1,n,1); res=deep[getlca(u,v)]; if(ans2<res){ ans1=p,ans2=res; } printf("%d %d\n",ans1,ans2); } return 0; } /* 6 2 1 2 1 2 4 2 3 1 4 */