求助主席树练习题
查看原帖
求助主席树练习题
768195
ty_mxzhn楼主2023/7/13 16:08

第四个点WA,陆陆续续调了一个星期,但还找不到原因。

#include <cstdio>
#include <iostream>
#define int long long
using namespace std;

int n,m,d,y,x,a[100007],ans,P[200007],invp[200007],v[200007],Pc=1,MX,PD,Lst[200007];
struct node{
	int ls,us,sum,maxn,prod;
}tr[6000007];
int tot,rt[250007];
const int maxa=400007;
const int mod =1e9+7;
int Q(int x){
	return max(1ll,x); 
} 
void pushup(int k){
	tr[k].sum =      tr[tr[k].ls].sum  +  tr[tr[k].us].sum       ;
	tr[k].maxn=max(  tr[tr[k].ls].maxn ,  tr[tr[k].us].maxn )    ;
	tr[k].prod=   (  tr[tr[k].ls].prod *  tr[tr[k].us].prod )%mod;
}
void print(int k,int lb=1,int ub=maxa){
	if(k==0) return;
	int mid=(lb+ub)>>1;
	if(tr[k].ls) printf("%lld[%lld,%lld,%lld] %lld[%lld,%lld,%lld]\n",k,lb,ub,tr[k].sum,tr[k].ls,lb   ,mid,tr[tr[k].ls].sum);
	if(tr[k].us) printf("%lld[%lld,%lld,%lld] %lld[%lld,%lld,%lld]\n",k,lb,ub,tr[k].sum,tr[k].us,mid+1,ub ,tr[tr[k].us].sum);
	print(tr[k].ls,lb   ,mid);
	print(tr[k].us,mid+1,ub );
}
void nw(int &k,int lt,int lb=1,int ub=maxa){
	//printf("%lld ",k);
	if(lt==0) return;
	if(k==0){
		k=lt;
		return;
	}
	if(lb==ub){
		tr[k].maxn=max(  tr[k].maxn ,  tr[lt].maxn )    ;
		tr[k].sum =      tr[k].sum  +  tr[lt].sum       ;
		tr[k].prod=tr[lt].prod;
		return;
	}
	int mid=(lb+ub)>>1;
	nw(tr[k].ls,tr[lt].ls,lb   ,mid);
	nw(tr[k].us,tr[lt].us,mid+1,ub );
	pushup(k);
	return;
}
void upd(int &k,int a,int b,int x,int y,int lb=1,int ub=maxa){
	if(k==0) k=++tot,tr[k].prod=1;
	if(a<=lb&&ub<=b){
		tr[k].sum +=x;
		tr[k].maxn+=x;
		tr[k].prod =y;
		return;
	}
	int mid=(lb+ub)>>1;
	if(a<=mid) upd(tr[k].ls,a,b,x,y,lb   ,mid);
	if(b> mid) upd(tr[k].us,a,b,x,y,mid+1,ub );
	pushup(k);
} 
void query(int k,int a,int b,int lb=1,int ub=maxa){
	if(k==0) return; 
	if(a<=lb&&ub<=b){
		MX=max(MX,tr[k].maxn);
		PD=(PD*tr[k].prod)%mod;
	}
	int mid=(lb+ub)>>1,ans=0;
	if(a<=mid) query(tr[k].ls,a,b,lb   ,mid);
	if(b> mid) query(tr[k].us,a,b,mid+1,ub );
}
void init(){
	v[1]=1;
	for(int i=2;i<=200000;i++){
		if(!v[i]){
			
			for(int j=2*i;j<=200000;j+=i){
				//printf("%lld ",j);
				v[j]=true;
			}P[Pc++]=i;
		}
		
	}
}
void add(int x,int i){
	for(int j=1;j<=450;j++){
		if(x==1) break;
		while(x%P[j]==0){
			x=x/P[j];
			upd(rt[j],i,i,1,1);
		}
	}
	if(x==1) return;
	upd(rt[451+i],i,i,0,x);
	if(Lst[x]) upd(rt[451+i],Lst[x],Lst[x],0,1);
	Lst[x]=i;
}
int qpow(int a,int b){
	int ans=1;
	while(b){
		if(b&1) ans=ans*a%mod;
		a=a%mod*a%mod;
		b=b>>1;
	}
	return ans;
}
signed main(){
	init();
	tr[0].prod=1;
	//for(int i=1;i<=450;i++) printf(" %lld\n",P[i]);
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]),add(a[i],i);
		nw(rt[451+i],rt[450+i]);
	}
	//for(int i=1;i<=450;i++) printf(" %lld\n",P[i]);
	scanf("%lld",&m);
	PD=0;
	for(int i=1;i<=m;i++){
		scanf("%lld%lld",&x,&y);
		x=((x+PD)%n)+1,y=((y+PD)%n)+1;
		//printf("%lld %lld\n",x,y);
		if(x>y) swap(x,y);
		PD=1;
		query(rt[451+y],x,y);
		for(int j=1;j<=450;j++){
			MX=0;
			query(rt[j],x,y);
			//if(j<=5) printf(" %lld\n",MX);
			PD=(PD*qpow(P[j],MX))%mod;
		}
		
		printf("%lld\n",PD);
	}
	return 0;
}
2023/7/13 16:08
加载中...