题意十分甚至有九分的简单,但是这个东西似乎是不好做的,我想不出来任何已知的 log 数据结构维护它。
突然发现这个东西增长是缓慢的,我于是乎写了个程序验证,最后发现答案最多是 1e6 左右的一个数。
果然有的时候观察答案上下界有奇效。
我们发现可以使用差分转化为对于每个点跳多少次。
因为这个跳的值域是很小的,而且有 2 次幂的可划分性,所以我们上倍增就行了。
代码↓
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int MN=2e6+216;
int lg[MN], jump[MN][22];
int n, m, d[MN], a[MN];
int main(){ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);lg[0]=-1; for(int i=1; i<MN; ++i) lg[i]=lg[i>>1]+1;cin>>n>>m; for(int i=1; i<=n; ++i) cin>>a[i];for(int i=1; i<MN; ++i) jump[i][0]=i+lg[i];for(int j=1; j<=21; ++j){for(int i=1; i<MN; ++i){jump[i][j]=jump[jump[i][j-1]][j-1];}}for(int i=1; i<=m; ++i){int l, r; cin>>l>>r;d[l]++; d[r+1]--;}for(int i=1; i<=n; ++i) d[i]+=d[i-1];for(int i=1; i<=n; ++i){int res=a[i];for(int j=0; j<=21; ++j){if(d[i]&(1<<j)){res=jump[res][j];}}cout<<res<<' ';}return 0;
}