Problem Description
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) .
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.
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
首先有一个性质,一个数A不断地做取模操作,最多经过logA次就会变为0
这样我们就可以每次查找当前位置下一个不大于它的数的位置然后取模继续查找
用线段树实现的话就是先找左子数,左子树没有再找右子树就可以了
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct tree
{
int l,r;
int mi,x;
}tr[800001];
int a[100001];
inline void build(int p,int l,int r)
{
tr[p].l=l;
tr[p].r=r;
if(l!=r)
{
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
tr[p].mi=min(tr[p*2].mi,tr[p*2+1].mi);
if(tr[p].mi==tr[p*2].mi)
tr[p].x=tr[p*2].x;
else
tr[p].x=tr[p*2+1].x;
}
else
{
tr[p].mi=a[l];
tr[p].x=l;
}
}
tree nw;
inline tree ask(int p,int l,int r,int x)
{
if(tr[p].mi>x)
return nw;
if(tr[p].l==tr[p].r)
{
// printf("%d %d %d\n",tr[p].l,tr[p].r,tr[p].mi);
return tr[p];
}
else
{
int mid=(tr[p].l+tr[p].r)/2;
tree ans1=nw,ans2=nw;
if(l<=mid&&tr[p*2].mi<=x)
ans1=ask(p*2,l,r,x);
if(ans1.mi!=0)
return ans1;
if(r>mid&&tr[p*2+1].mi<=x)
return ask(p*2+1,l,r,x);
return nw;
}
}
inline int cal(int l,int r)
{
int d=a[l];
while(l<r)
{
tree xt=ask(1,l+1,r,d);
if(xt.mi==0)
return d;
l=xt.x;
d%=xt.mi;
}
return d;
}
int main()
{
// freopen("1008.in","r",stdin);
// freopen("1008.out","w",stdout);
int T;
while(scanf("%d",&T)!=EOF)
{
while(T>0)
{
T--;
int n;
scanf("%d",&n);
int i;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
int m;
scanf("%d",&m);
int l,r;
for(i=1;i<=m;i++)
{
scanf("%d%d",&l,&r);
printf("%d\n",cal(l,r));
}
}
}
return 0;
}