http://www.cnblogs.com/kuangbin/archive/2013/07/30/3225627.html
题意:给出一个n和1到n的某个排列,询问q次,每次询问[l,r]区间内任意挑两个数,最大公约数的最大值是多少。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<set>
#include<map>
#include<list>
#include<queue>
#include<vector>
#define tree int o,int l,int r
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define lo o<<1
#define ro o<<1|1
#define ULL unsigned long long
#define LL long long
#define UI unsigned int
#define inf 0x7fffffff
#define eps 1e-7
#define N 100009
#define M 9901
using namespace std;
int T,n,m,k,t,maxv;
int a[N],b[N];
int c[N];
int ans[N];
struct Node
{
int l,r,id;
bool operator<(const Node &a)const
{
return l>a.l;
}
} node[N];
void add(int x,int val)
{
while(x<N)
{
c[x]=max(c[x],val);
x+=(x&-x);
}
}
int sum(int x)
{
int ans=0;
while(x>0)
{
ans=max(ans,c[x]);
x-=(x&-x);
}
return ans;
}
void init()
{
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ex.in","r",stdin);
#endif
scanf("%d",&T);
// while(scanf("%d",&n)==1)
while(T--)
{
init();
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(int i=0; i<m; ++i)
{
scanf("%d%d",&node[i].l,&node[i].r);
node[i].id=i;
}
sort(node,node+m);
int k=0;
for(int i=n; i>=1; i--)
{
for(int j=1; j*j<=a[i]; j++)
if(a[i]%j==0)
{
if(b[j]!=0)
{
add(b[j],j);
}
b[j]=i;
if(b[a[i]/j]&&j*j!=a[i])//WA
{
add(b[a[i]/j],a[i]/j);
}
b[a[i]/j]=i;
}
while(k<m&&node[k].l>=i)
{
ans[node[k].id]=sum(node[k].r);
k++;
}
}
for(int i=0; i<m; i++)
printf("%d\n",ans[i]);
}
return 0;
}