hdu 4630 No Pain No Game 多校第三场

来源:互联网 发布:制作手机视频的软件 编辑:程序博客网 时间:2024/05/18 13:44

对每个数x,用pre[x]表示x的倍数中,在当前位置之前,最靠右的位置,在考虑当前数a[i]的所有约数v,对于所有l<=pre[v]的询问,v都是可能的答案。用树状数组来维护。


#include <cstdio>#include <cstring>#include <iostream>#include <string>#include <vector>#include <algorithm>using namespace std;const int MAXN = 50005;int c[MAXN];int ans[MAXN],a[MAXN];int pre[MAXN];vector<int> divv[MAXN];//约数int n,Q;void init(){    for(int i=1;i<MAXN;i++)        for(int j=i;j<MAXN;j+=i)        divv[j].push_back(i);}void updata(int pos,int v){    for(int i=pos;i<=n;i+=i&(-i))    {        c[i]=max(c[i],v);    }}int query(int p){    int res=0;    for(int i=p;i>0;i-=i&(-i))    {        res=max(res,c[i]);    }    return res;}struct pp{    int l,r,id;    bool operator < (const pp a)const{        return r<a.r;    }}q[MAXN];int main(){    init();    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        scanf("%d",&Q);        for(int i=0;i<Q;i++)        {            scanf("%d%d",&q[i].l,&q[i].r);            q[i].id=i;        }        sort(q,q+Q);        memset(c,0,sizeof(c));        memset(pre,0,sizeof(pre));        for(int i=1,k=0;i<=n;i++)        {            int x=a[i],siz=divv[x].size();            for(int j=0;j<siz;j++)            {                int v=divv[x][j];                if(pre[v]!=0)                updata(n-pre[v]+1,v);                pre[v]=i;            }            while(q[k].r==i&&k<Q)            {                ans[q[k].id]=query(n+1-q[k].l);                k++;            }        }        for(int i=0;i<Q;i++)            printf("%d\n",ans[i]);    }    return 0;}


原创粉丝点击