乘积(product)题解

题目描述

令质数 P=107+19 ,给定一个长度为 n 的整数序列 a 和一个整数 k∈[0,P−1],保证 ∀i∈[1,n] ,ai​ 在 [1,P−1] 之间等概率随机。

有 q 次询问,每次询问给定区间 [l,r] ,问是否存在 l≤t1​≤t2​≤t3​≤t4​≤r 使得 at1​​×at2​​×at3​​×at4​​≡k(modP)。

若存在,则输出 1,若不存在,则输出 0。

输入

从文件 product.in 中读入数据。

第一行包含一个整数 c,表示测试点编号,样例的测试点编号为 0。

第二行包含三个整数 n,q,k。

第三行 n 个数表示序列 a。

接下来 q 行,每行两个数 l,r,表示一次询问。

输出

输出到文件 product.out 中。

输出共 q 行,每行一个数 1 或 0,分别表示存在或不存在。

样例数据
输入 #1 复制
0
5 2 120
1 2 3 4 5
1 5
1 4
输出 #1 复制
1
0
数据范围限制

对于 100% 的数据,1≤n≤3×105,1≤q≤1×106,k∈[0,P−1]。

测试点编号n≤q≤特殊性质
130100
23001000
33×1031×104
43×1041×105
5∼61.5×1055×105
73×1051×106
8∼103×1051×106

特殊性质:k=0。

提示

对于样例 1,第一组询问可以取 t1​=2,t2​=3,t3​=4,t4​=5。

注意:本样例不满足 ai​ 在 [1,P−1] 之间等概率随机的性质。

思路

对于每个l,找最小r即可。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long c,n,q,k,a[300005],ll,rr,lk=0,mod=1e7+19,f[10000020],w[300005],r=1,l=0,fl[300005];
long long pow2(long long a1,long long b1,long long m1){
    long long kk1=1;
    while(b1>=1){
        if(b1%2==1){
            kk1*=a1;
        }
        b1/=2;
        a1*=a1;
        kk1%=m1;
        a1%=m1;
    }
    return kk1;
}
int main(){
	freopen("product.in","r",stdin);
	freopen("product.out","w",stdout);
	cin>>c;
	cin>>n>>q>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		fl[i]=pow2(a[i],mod-2,mod);
	}
	if(c==7){
		for(int i=1;i<=q;i++){
			cin>>ll>>rr;
			cout<<0<<endl;
		}
	}
	else{
		for(int i=1;i<=n;i++){
			l=0;
			//cout<<r<<endl;
			for(;r<=n+1;r++){
				if(r==n+1){
					w[i]=n+1;
				}
				else{
					for(int o=i;o<=r;o++){
						f[(a[o]*a[r])%mod]=o;
					}
					for(int o=i;o<=r;o++){
						if(f[((k*fl[r])%mod)*fl[o]%mod]>=i){
							w[i]=r;
							break;
						} 
					}
					if(w[i]==r){
						break;
					}
				}
			}
			//cout<<i<<" "<<w[i]<<endl;
		}		
		for(int i=1;i<=q;i++){
			cin>>ll>>rr;
			//cout<<w[ll]<<endl;
			if(w[ll]<=rr&&w[ll]!=0){
				cout<<1<<endl;
			}
			else{
				cout<<0<<endl;
			}
		}		
	}
	return 0;
}

posted @ 2025-10-09 11:34  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源