您的位置:首页 > 其它

hdu 4630 多校第二场 树状数组,离线处理

2013-07-31 18:01 531 查看
1-n的排列,询问(l,r)之间的最大的gcd(a,b)
(1)离线处理,询问对按右端点排序,边插入边查询,使在处理(l,r)时,(l,r)内的该插入的已经插入
(2)枚举每个数的约数,记录到当前位置为止,上一个x的倍数出现的位置prev(x)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
#define N 100500
struct Q
{
int l,r,idx;
}que
;
int b
,ans
,n,q,a
;

bool cmp(Q ll, Q rr)
{
return ll.r<rr.r;
}
void update(int x,int val)
{
while(x)
{
b[x]=max(b[x],val);
x-=x&(-x);
}
}
int query(int x)
{
int res=0;
while(x<=n)
{
res=max(res,b[x]);
x+=x&(-x);
}
return res;
}
vector<int>divs
;
int pre
;
int main ()
{
for(int i=1;i<N;++i)
for(int j=i;j<N;j+=i)
divs[j].push_back(i);
int T;scanf("%d",&T);
while(T--)
{
memset(b,0,sizeof(b));
memset(pre,0,sizeof(pre));
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
scanf("%d",&q);
int u,v;
for(int i=1;i<=q;++i)
{
scanf("%d%d",&u,&v);
que[i].l=u;que[i].r=v;que[i].idx=i;
}
sort(que+1,que+1+q,cmp);
for(int i=1,k=1;i<=n;++i)
{
int x=a[i];
for(int j=0;j<divs[x].size();++j)
{
int pp=divs[x][j];
if(pre[pp])
update(pre[pp],pp);
pre[pp]=i;
}
while(que[k].r==i&&k<=q)
{
ans[que[k].idx]=query(que[k].l);
k++;
}
}
for(int i=1;i<=q;++i)
printf("%d\n",ans[i]);
}
return 0;
}


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