倍增50pts求大佬条
查看原帖
倍增50pts求大佬条
1176325
badn楼主2024/11/13 16:43
#include<bits/stdc++.h>
#define gc getchar()
#define rep(u,x,y) for(ll u=x;u<=y;++u)
using namespace std;
typedef long long ll;
const ll N=1e6+1,Mod=1e9+7;
ll read(){
	ll x=0,w=1;
	char ch=gc;
	while(ch<'0'||ch>'9')((ch=='-')&&(w=-1,0)),ch=gc;
	while(ch>='0'&&ch<='9')x=(x<<3)+x+x+(ch^48),ch=gc;
	return x*w;
}
bool readb(){
	char ch=gc;
	while(ch<'0'||ch>'9')ch=gc;
	return ch^48;
}
void wrt(ll x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)wrt(x/10);
	putchar(x%10^48);
}
bool a[N];
ll pre[N],n,m,q,ins,idx,x,y,ans,S;
struct {
	ll val,st;
}to[N][31];
ll lowbit(ll x){return x&-x;}
void tomod(ll&x){x=(x-1)%n+1;}//将超过n的数取模回1~n 
ll find_low(ll x){//二分小于等于第一个数 
	ll l=0,r=2*idx,mid;
	while (l < r){
		mid = (l + r + 1) >> 1;
		if (pre[mid]<=x)  l = mid;
		else r = mid - 1;
	}
	return pre[l];
}
void init(){//倍增预处理 
	rep(i,1,30){
		rep(pos,1,n){
			to[pos][i].st=to[pos][i-1].st;
			
			to[pos][i].val=to[to[pos][i-1].val][i-1].val;//核心式子 
			to[pos][i].st+=to[to[pos][i-1].val][i-1].st;//累计跳跃长度 
			
			to[pos][i].st%=Mod;
		}
	}
}
int main(){
//	freopen("kingdom4.in","r",stdin);
	n=read(),m=read(),q=read(),ins=m%n;//(m/n)是直接跳过的一整圈,ins是在圈内跳跃的长度 
	rep(i,1,n){
		a[i]=readb();
		if(a[i])++idx,pre[idx]=pre[idx+n]=i;
	}
	rep(i,1,idx)pre[i+idx]=pre[i]+n;//倍长
	rep(pos,1,n){
		ll t=find_low(pos+ins);
		/*特判m>n且跳不到下一个位置的方案,但加了之后少了5分,不知错在哪里,故舍去 
		if(!t){
			t=find_low(pos+ins+n);
			to[pos][0].val=max((pos+1),t);
			to[pos][0].st=max(int(m/n-1)*n,0ll)+to[pos][0].val-pos;//st为跳跃次数所得的跳跃长度 
			tomod(to[pos][0].val);
		}else{
		*/
		
		to[pos][0].val=max((pos+1),t);
		to[pos][0].st=int(m/n)*n+to[pos][0].val-pos;//st为跳跃次数所得的跳跃长度 
		tomod(to[pos][0].val);//取模使落点回到1~n,然后 val为跳到的T中的i个 
		
		/*}*/
	}
//	rep(i,1,n)cout<<i<<":to->"<<to[i][0].val<<",get->"<<to[i][0].st<<'\n';//调试,输出t_i的下一步跳到的位置 
	init();
	while(q--){
		S=x=read(),y=read(),ans=0;
		tomod(x);//毒点:起始点可能大于n!!! 
		while(y){
			int len=log2(lowbit(y));//取最小跳跃次数跳 
			ans=(ans+to[x][len].st)%Mod; 
			x=to[x][len].val;
			y-=lowbit(y);
		}
		wrt((S+ans)%Mod),putchar('\n');
	}
	return 0;
}
2024/11/13 16:43
加载中...