乘积(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≤ | 特殊性质 |
|---|---|---|---|
| 1 | 30 | 100 | 无 |
| 2 | 300 | 1000 | 无 |
| 3 | 3×103 | 1×104 | 无 |
| 4 | 3×104 | 1×105 | 无 |
| 5∼6 | 1.5×105 | 5×105 | 无 |
| 7 | 3×105 | 1×106 | 有 |
| 8∼10 | 3×105 | 1×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;
}

浙公网安备 33010602011771号