1. 程式人生 > >Codeforces 932D - Tree

Codeforces 932D - Tree

clu pan 最大 back 代碼 遞增 tree cin bsp

932D - Tree

思路:

樹上倍增

anc[i][u]:u的2^i祖先

mx[i][u]:u到它的2^i祖先之間的最大值,不包括u

pre[i][u]:以u開始的遞增序列的2^i祖先

sum[i][u]:以u開始遞增序列從u到2^i祖先的和,不包括u

代碼:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))


const int N=4e5+5
; const ll INF=1e15; int anc[20][N],pre[20][N]; ll sum[20][N],w[N],mx[20][N]; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int q,cnt=1,op; ll l,r,last=0; w[0]=INF; for(int i=0;i<20;i++)sum[i][1]=sum[i][0]=mx[i][1]=mx[i][0]=INF; cin>>q;
while(q--){ cin>>op>>l>>r; l^=last; r^=last; if(op==1){ anc[0][++cnt]=l; w[cnt]=r; mx[0][cnt]=w[l]; for(int i=1;i<20;i++){ anc[i][cnt]=anc[i-1][anc[i-1][cnt]]; mx[i][cnt]
=max(mx[i-1][cnt],mx[i-1][anc[i-1][cnt]]); } int t=cnt; for(int i=19;i>=0;i--){ if(mx[i][t]<w[cnt]){ t=anc[i][t]; } } pre[0][cnt]=anc[0][t]; sum[0][cnt]=w[anc[0][t]]; for(int i=1;i<20;i++){ pre[i][cnt]=pre[i-1][pre[i-1][cnt]]; sum[i][cnt]=sum[i-1][cnt]+sum[i-1][pre[i-1][cnt]]; } } else{ int ans=0; if(w[l]<=r){ ans=1; r-=w[l]; for(int i=19;i>=0;i--){ if(sum[i][l]<=r){ r-=sum[i][l]; l=pre[i][l]; ans+=1<<i; } } } last=ans; cout<<ans<<endl; } } return 0; }

Codeforces 932D - Tree