AtCoder Beginner Contest 438

E - Heavy Buckets

倍增

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define yes cout << "Yes" << endl
#define no cout << "No" << endl
#define pii pair<int,int>
#define ll long long
#define pb push_back
#define ft first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f

const int N = 200010;
int f[N][33]; ll sum[N][33];
int a[N];

void solve(){
    int n, q; cin >> n >> q;
    for(int i = 1; i <= n; i ++){
        cin >> a[i];
    }

    for(int i = 1; i <= n; i ++){
        f[i][0] = a[i];//2^i之后在哪个点
        sum[i][0] = i;//这个水桶2^i次操作后多了多少水
    }

    for(int j = 1; j <= 30; j ++){
        for(int i = 1; i <= n; i ++){
            f[i][j] = f[f[i][j - 1]][j - 1];
            sum[i][j] = sum[i][j - 1] +sum[f[i][j - 1]][j - 1];
        }
    }

    while(q --){
        int t, b; cin >> t >> b;
    
        ll ans = 0;
        for(int j = 30; j >= 0; j --){
            if(t & (1<<j)){
                ans += sum[b][j];
				b = f[b][j];
				t -= (1 << j);
            }
        }
        cout << ans << '\n';
    }
    
}

signed main(){
    std::ios::sync_with_stdio(false);
    int T = 1; 
    // cin >> T;
    while(T--){
        solve();
    }
}
posted @ 2026-01-10 18:21  arin876  阅读(4)  评论(0)    收藏  举报