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

No Pain No Game

2014-10-03 10:58 113 查看
hdu4630:http://acm.hdu.edu.cn/showproblem.php?pid=4630

题意:给定一个排序,求区间最大GCD。

题解:离散树状数组。首先把查询按左端点从大到小排序。然后用树状数组来维护每个位置出现的最大的公约数。枚举每个数的约数,记录到当前位置为止,上一个x的倍数出现的位置b[x];

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int N=5e4+19;
int a
,c
,b
,ans
;
int n,m;
int lowbit(int x){
return x&(-x);
}
void add(int x,int val){
while(x<=n){
c[x]=max(c[x],val);
x+=lowbit(x);
}
}
int getsum(int x){
int sum=0;
while(x>0){
sum=max(sum,c[x]);
x-=lowbit(x);
}
return sum;
}
struct Node{
int l,r;
int id;
bool operator<(const Node a)const{
return l>a.l;
}
}num
;
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&num[i].l,&num[i].r);
num[i].id=i;
}
sort(num+1,num+m+1);
int j=n;
for(int i=1;i<=m;i++){
for(;j>=num[i].l;j--){
for(int k=1;k*k<=a[j];k++){
if(a[j]%k==0){
if(b[k]){
add(b[k],k);
}
b[k]=j;
if(k*k!=a[j]){
if(b[a[j]/k]){
add(b[a[j]/k],a[j]/k);
}
b[a[j]/k]=j;
}
}
}
}
ans[num[i].id]=getsum(num[i].r);
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: