60 pts 倍增求调
查看原帖
60 pts 倍增求调
789564
queenbee楼主2024/11/9 13:13
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=4e5+10;
const int Mod=1e9+7;
const int M=1e18;
int n,m,q;
string S;
int s,k;
int cnt,tmp,sum,maxh,maxm;
int far[N];
int fa[N/2][100],val[N/2][100];
int base[100];
inline int Log(int x){
	register int cnt=0;
	while(x){
		cnt++;
		x>>=1; 
	}
	return cnt;
}
signed main(){
//	freopen("kingdom3.in","r",stdin);
//	freopen("kingdom.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m>>q;
	cin>>S;
	S=' '+S+S;
	for(int i=1;i<=2*n;i++){
		if(S[i]=='1'){
			far[i]=i;
		}
		else{
			far[i]=far[i-1];
		}
	}
	tmp=(m/n)%Mod;
	cnt=m%n;
	if(cnt==0){
		cnt=n;
		tmp--;
	}
	for(int i=1;i<=n;i++){
		if(far[i+cnt]>i){
			int x=far[i+cnt]%n;
			if(x==0){
				x=n;
			}
			fa[i][0]=x;
			val[i][0]=((tmp*(n%Mod))%Mod+far[i+cnt]-i)%Mod;
		}
		else{
			int x=(i+1)%n;
			if(x==0){
				x=n;
			}
			val[i][0]=1;
			fa[i][0]=x;
		}
	}
//	for(int i=1;i<=n;i++){
//		cout<<val[i][0]<<" ";
//	}
//	cout<<endl;
	maxh=Log(M);
	for(int j=1;j<=maxh;j++){
		for(int i=1;i<=n;i++){
			fa[i][j]=fa[fa[i][j-1]][j-1];
			val[i][j]=(val[fa[i][j-1]][j-1]+val[i][j-1])%Mod;
		}
	}
	base[0]=1;
	for(int i=1;i<=maxh;i++){
		base[i]=base[i-1]*2;
	}
	while(q--){
		sum=0;
		cin>>s>>k;
		maxm=Log(k);
		int ss=s;
		s%=n;
		if(s==0){
			s=n;
		}
		for(int i=maxm;i>=0;i--){
//			cout<<"sum:"<<sum<<endl;
//			cout<<i<<" "<<base[i]<<endl;
			if(base[i]<=k){
				sum+=val[s][i];
				sum%=Mod;
				s=fa[s][i];
				k-=base[i];
			}
		}
		printf("%lld\n",(ss%Mod+sum%Mod)%Mod);
	}
	return 0;
} 
2024/11/9 13:13
加载中...