The shorter, the simpler. With this problem, you should be convinced of this truth.
You are given an array A of N postive integers, and M queries in the form (l,r). A function F(l,r) (1≤l≤r≤N) is defined as:
F(l,r)={AlF(l,r−1) modArl=r;l<r.
You job is to calculate F(l,r), for each query (l,r)
.
Input
There are multiple test cases.
The first line of input contains a integer T
, indicating number of test cases, and T test cases follow.
For each test case, the first line contains an integer N(1≤N≤100000).
The second line contains N space-separated positive integers: A1,…,AN (0≤Ai≤109).
The third line contains an integer M denoting the number of queries.
The following M lines each contain two integers l,r (1≤l≤r≤N)
, representing a query.
Output
For each query(l,r)
, output F(l,r)
on one line.
Sample Input
1 3 2 3 3 1 1 3
Sample Output
2
题意:给你一个序列,给出多个询问l,r,求a[l]%a[l+1]%a[l+2]%...%a[r].的结果
由于取余比自己大的数字没有意义,所以只要预处理一下,比自己小的数字的位置,只取余
那些比自己小于等于的数字,所以很多位置可以跳过不计
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100005;
int arr[N],pos[N];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&arr[i]);
for(int i=1;i<=n;i++){ //预处理需要计算的位置
int tmp=n+1;
for(int j=i+1;j<=n;j++){
if(arr[j]<=arr[i]){
tmp=j;
break;
}
}
pos[i]=tmp;
}
int m;
scanf("%d",&m);
while(m--){
int l,r;
scanf("%d%d",&l,&r);
int ans=arr[l];
for(int i=l+1;i<=r;i=pos[i]) //根据预处理结果进行取模
ans%=arr[i];
printf("%d\n",ans);
}
}
return 0;
}