您的位置:首页 > 大数据 > 人工智能

HDU-4630-No Pain No Game

2013-08-14 20:19 274 查看
这个题也就是说给你一列数(1~n),然后给你出一些询问,让你找出询问区间的2个数的最大公约数

思路:

离线化计算,对区间进行排序后从后面往前算,用树状数组进行维护,不断更新最大因子

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=50100;
struct node
{
int l;
int r;
int pos;
bool operator <(const node& a)const
{
return l<a.l;
}
}q[maxn];
int n,m,a[maxn],pre[maxn],c[maxn],ans[maxn];
int lowbit(int x)
{
return x&(-x);
}
void Update(int i,int val)
{
for(;i<=n;c[i]=max(c[i],val),i+=lowbit(i));
}
int Sum(int i)
{
int ans=0;
for(;i>0;ans=max(ans,c[i]),i-=lowbit(i));
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(pre,0,sizeof(pre));
memset(c,0,sizeof(c));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].pos=i;
}
sort(q+1,q+m+1);
for(int i=m,j=n;i>0;)
{
while(j>=1&&j>=q[i].l)
{
for(int k=1;k*k<=a[j];k++)
if(a[j]%k==0)
{
if(pre[k])
Update(pre[k],k);
pre[k]=j;
if(k*k==a[j])
break;
if(pre[a[j]/k])
Update(pre[a[j]/k],a[j]/k);
pre[a[j]/k]=j;
}
j--;
}
while(q[i].l>j)
{
ans[q[i].pos]=Sum(q[i].r);
i--;
}
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: