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();
}
}

浙公网安备 33010602011771号