CodeForces - 932D Tree(树上倍增,好题)
生活随笔
收集整理的這篇文章主要介紹了
CodeForces - 932D Tree(树上倍增,好题)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出一棵樹,初始時只有一個節點1,權值為0,后續有 n 個操作,每次操作分為兩種情況:
題目分析:因為操作二需要每次按照要求往祖先節點上跳,我們不妨設計一下倍增來處理所需要解決的問題
有了這兩個數組的定義后,那么我們在插入時,可以logn維護一下這兩個數組,在查詢時,也可以logn獲得答案,有很多細節,具體實現看代碼吧:
代碼:
#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<set> #include<cmath> #include<sstream> #include<unordered_map> using namespace std;typedef long long LL;const LL inf=0x3f3f3f3f3f3f3f3f;const int N=4e5+100;LL last,dp[N][25],sum[N][25],w[N],cur;void add(LL u,LL val) {u^=last;val^=last;w[++cur]=val;if(w[cur]<=w[u])//處理dp[u][0]dp[cur][0]=u;else{for(int i=20;i>=0;i--)if(w[cur]>w[dp[u][i]])u=dp[u][i];dp[cur][0]=dp[u][0];}if(dp[cur][0]==0)//處理sum[u][0]sum[cur][0]=inf;elsesum[cur][0]=w[dp[cur][0]];for(int i=1;i<=20;i++)//維護dp數組和sum數組{dp[cur][i]=dp[dp[cur][i-1]][i-1];if(dp[cur][i]==0)sum[cur][i]=inf;elsesum[cur][i]=sum[cur][i-1]+sum[dp[cur][i-1]][i-1];} }LL query(LL u,LL val) {u^=last;val^=last;if(w[u]>val)return 0;LL ans=1;val-=w[u];for(int i=20;i>=0;i--)//統計答案{if(val>=sum[u][i]){val-=sum[u][i];ans+=(1<<i);u=dp[u][i];}}return ans; }void init()//初始化sum數組到所有不可能到達的位置為無窮大 {w[0]=inf;w[1]=0;last=0;cur=1;for(int i=0;i<=20;i++)sum[1][i]=inf; }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);init();int n;scanf("%d",&n);while(n--){LL op,p,q;scanf("%lld%lld%lld",&op,&p,&q);if(op==1)add(p,q);elseprintf("%lld\n",last=query(p,q));}return 0; }?
總結
以上是生活随笔為你收集整理的CodeForces - 932D Tree(树上倍增,好题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 1000C C
- 下一篇: CodeForces - 467C Ge