#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 100005
using namespace std;
int treemaxnum[N*200],treemaxlson[N*200],treemaxrson[N*200];
int treenumnum[N*20],treenumlson[N*20],treenumrson[N*20];
int prime[N],pri[N],pre[N],pred[N],n,m,a[N],p[N];
int cntmax,cntnum,rootmax[N],rootnum[N];
void buildmax(int &o,int l,int r,int x,int y)
{
if(!o)o=++cntmax;
if(l==r)
{
treemaxnum[o]=max(treemaxnum[o],y);
return;
}
int mid=(l+r)>>1;
if(x<=mid)buildmax(treemaxlson[o],l,mid,x,y);
else buildmax(treemaxrson[o],mid+1,r,x,y);
treemaxnum[o]=max(treemaxnum[treemaxlson[o]],treemaxnum[treemaxrson[o]]);
}
int querymax(int o,int l,int r,int x,int y)
{
if(!o)return -1;
if(l==x&&r==y)return treemaxnum[o];
int mid=(l+r)>>1;
if(y<=mid)return querymax(treemaxlson[o],l,mid,x,y);else
if(x>mid)return querymax(treemaxrson[o],mid+1,r,x,y);else
return max(querymax(treemaxlson[o],l,mid,x,mid),querymax(treemaxrson[o],mid+1,r,mid+1,y));
}
void buildnum(int &o,int l,int r,int x)
{
if(!o)o=++cntnum;
if(l==r)
{
treenumnum[o]++;
return;
}
int mid=(l+r)>>1;
if(x<=mid)buildnum(treenumlson[o],l,mid,x);
else buildnum(treenumrson[o],mid+1,r,x);
treenumnum[o]=treenumnum[treenumlson[o]]+treenumnum[treenumrson[o]];
}
int querynum(int o,int l,int r,int x,int y)
{
if(!o)return 0;
if(l==x&&r==y)return treenumnum[o];
int mid=(l+r)>>1;
if(y<=mid)return querynum(treenumlson[o],l,mid,x,y);else
if(x>mid)return querynum(treenumrson[o],mid+1,r,x,y);else
return querynum(treenumlson[o],l,mid,x,mid)+querynum(treenumrson[o],mid+1,r,mid+1,y);
}
int main()
{
freopen("gcd.in","r",stdin);
freopen("gcd.out","w",stdout);
memset(prime,true,sizeof(prime));
prime[1]=false;
int num=0;
treemaxnum[0]=-1;
for(int i=2;i<=N;i++)
{
if(prime[i])
{
pri[++num]=i;
pre[i]=1;
pred[i]=num;
}
for(int j=1;j<=num&&i*pri[j]<=N;j++)
{
prime[i*pri[j]]=false;
pre[i*pri[j]]=i;
if(i%pri[j]==0)break;
}
}
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
int k=a[i];
num=0;
while(k!=1)
{
p[++num]=k/pre[k];
k=pre[k];
}
sort(p+1,p+1+num);
num=unique(p+1,p+num+1)-p-1;
for(int j=1;j<=num;j++)
buildmax(rootmax[pred[p[j]]],1,n,i,a[i]);
}
for(int i=1;i<=n;i++)
buildnum(rootnum[a[i]],1,n,i);
while(m--)
{
int g,l,r;
scanf("%d%d%d",&g,&l,&r);
int k=g,mx=-1,sum=0;
num=0;
while(k!=1)
{
p[++num]=k/pre[k];
k=pre[k];
}
sort(p+1,p+1+num);
num=unique(p+1,p+num+1)-p-1;
for(int j=1;j<=num;j++)
mx=max(mx,querymax(rootmax[pred[p[j]]],1,n,l,r));
if(mx==-1)puts("-1 -1");else
{
sum=querynum(rootnum[mx],1,n,l,r);
printf("%d %d\n",mx,sum);
}
}
return 0;
}
最大公约数(gcd)
最新推荐文章于 2022-01-24 22:52:38 发布