P11894 「LAOI-9」Update

题意十分甚至有九分的简单,但是这个东西似乎是不好做的,我想不出来任何已知的 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;
}
posted @ 2025-10-15 20:43  BaiBaiShaFeng  阅读(3)  评论(0)    收藏  举报
Sakana Widget右下角定位