玄关,萌新求救码风优良
查看原帖
玄关,萌新求救码风优良
1104479
zombiell810975楼主2024/11/10 21:28

rt,思路貌似没问题

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const ll Q=(2e5)+5,M=(1e18)+5,N=(2e5)+5,MOD=(10e9)+7;
ll n,m,q,dp[N][65],mo=-1,st,k,now,dps[N][65],sum;
char s[N];
/*
思路: 
mo为距i点最远切距离小于m的s[mo]=='1'; 
dp为倍增求解第i点跳2^j步到达的点(dp[i][j]∈[1,n+m]);
dps为倍增求解第i点跳2^j布到达点所走的步数;
*/
int main(){
	scanf("%lld%lld%lld",&n,&m,&q);
	scanf("%s",s+1);
	for(ll i=1;i<=m%n;i++) {
		if(s[i]=='1') mo=i+n*(m/n);	
	}
	for(ll i=1;i<=n;i++) {
		if(s[(i+m-1)%n+1]=='1') mo=i+m;
		if(mo<=i) dp[i][0]=i+1;
		else dp[i][0]=mo;
		if(mo<=i) dps[i][0]=1;
		else dps[i][0]=mo-i;	
	}
	for(ll step=1;step<=61;step++) {
		for(ll i=1;i<=n;i++) {
			dp[i][step]=dp[(dp[i][step-1]-1)%n+1][step-1]; 
			dps[i][step]=(dps[i][step-1]%MOD+dps[(dp[i][step-1]-1)%n+1][step-1]%MOD)%MOD;
			//printf("step:%lld i:%lld dp:%lld\n",step,i,dp[i][step]);
		}
	}
	while(q--) {
		scanf("%lld%lld",&st,&k);
		now=st;
		sum=st;
		for(int i=61;i>=0;i--) {
			if(pow(2,i)<=k) {
				sum=(sum%MOD+dps[(now-1)%n+1][i]%MOD)%MOD;
				now=dp[(now-1)%n+1][i];
				k-=pow(2,i);
				if(k==0) break;
			}
		}
		printf("%lld\n",sum%MOD);
	}
	return 0;
}
2024/11/10 21:28
加载中...