社区讨论

分块还有前途吗

P13522[KOI 2025 #2] 机器人参与者 3已保存回复 11

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
11 条
当前快照
1 份
快照标识符
@mied2ot8
此快照首次捕获于
2025/11/25 17:16
3 个月前
此快照最后确认于
2025/11/25 18:35
3 个月前
查看原帖
rt,record
伪分块,可以看到就 TLE 一个点呢。
感觉理论上跑不到 2s,而且最后一个 Sub 也有点跑到了 1.7s,所以可能是我做法假了?
CPP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int B=500;

int n,q;
ll s[300005],d[300005];

ll f[300005];
int ne[300005];

ll g[300005];
int far[300005];

int main(){
	ios::sync_with_stdio(0);
	
	cin>>n;
	for(int i=1;i<=n;++i) cin>>s[i]>>d[i];
	
	for(int i=1;i<n;++i){
		for(int j=0;j<60;++j){
			++f[i];
			ll np=s[i]+d[i]*(1ll<<j);
			if(np<s[i+1]) f[i]+=d[i]*(1ll<<j);
			else{
				ne[i]=upper_bound(s+1,s+n+1,np)-s-1;
				f[i]+=np-s[ne[i]];
				break;
			}
		}
	}
	
	f[n]=1e18,s[0]=-1e18;
	
	for(int i=1;i<=n;++i){
		if(i>n-B){
			g[i]=1e18;
			continue;
		}
		int cur=i;
		while(cur<i+B){
			g[i]+=f[cur];
			cur=ne[cur];
		}
		far[i]=cur;
	}
	
	cin>>q;
	
	while(q--){
		ll p,t;
		cin>>p>>t;
		
		int cur=upper_bound(s+1,s+n+1,p)-s-1;
		
		if(t<p-s[cur]){
			cout<<p-t<<endl;
			continue;
		}
		
		t-=p-s[cur];
		
		while(t>=g[cur]){
			t-=g[cur];
			cur=far[cur];
		}
		
		while(t>=f[cur]){
			t-=f[cur];
			cur=ne[cur];
		}
		
		ll ans=s[cur];
		
		for(int j=0;j<60;++j){
			if(t==0) break;
			--t;
			if(t>=d[cur]*(1ll<<j)) t-=d[cur]*(1ll<<j);
			else ans=s[cur]+d[cur]*(1ll<<j)-t,t=0;
		}
		
		cout<<ans<<endl;
	}
	
	return 0;
}

回复

11 条回复,欢迎继续交流。

正在加载回复...