hdu 4630 No Pain No Game

http://acm.hdu.edu.cn/showproblem.php?pid=4630

离散化+树状数组

将数组 *a  从后向前遍历 遍历到 a[x] 的时候 再枚举a[x]的约数 假如 约数 k

last[k] 对应到 上一个k出现的位置  那么可被公约数 k 更新的区间是   last[k] --- 最后

把所有a[x]的约数都处理完之后  从 x 到任意 y(y>=x)形成的段的 最优解都可求

代码:

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<string>

#include<cstring>

#include<cmath>

#include<set>

#include<vector>

#include<list>

using namespace std;



typedef long long ll;

typedef pair<double,double>ppd;

const double PI = acos(-1.);

const double eps = (1e-9);

const int N=50001;

struct node

{

    int l,r;

    int index;

}q[N];

int a[N],last[N],ans[N];

int c[N];

int lowbit(int x)

{

    return x&(-x);

}

void update(int i,int k)

{

    while(i<N)

    {

        c[i]=max(c[i],k);

        i+=lowbit(i);

    }

}

int getM(int i)

{

    int tmp=0;

    while(i>=1)

    {

        tmp=max(tmp,c[i]);

        i-=lowbit(i);

    }

    return tmp;

}

bool cmp(const node &x,const node &y)

{

    return x.l>y.l;

}

int main()

{

    //freopen("data.in","r",stdin);

    int T;

    scanf("%d",&T);

    while(T--)

    {

       int n;

       scanf("%d",&n);

       for(int i=1;i<=n;++i)

       scanf("%d",&a[i]);

       int Q;

       scanf("%d",&Q);

       for(int i=0;i<Q;++i)

       {

           scanf("%d %d",&q[i].l,&q[i].r);

           q[i].index=i;

       }

       sort(q,q+Q,cmp);

       memset(c,0,sizeof(c));

       memset(last,-1,sizeof(last));

       int ln=0;

       for(int i=n;i>=1;--i)

       {

           for(int x=1;x*x<=a[i];++x)

           if(a[i]%x==0)

           {

               if(last[x]!=-1)

               update(last[x],x);

               last[x]=i;

               int y=a[i]/x;

               if(x==y)

               continue;

               if(last[y]!=-1)

               update(last[y],y);

               last[y]=i;

           }

           while(ln<Q&&q[ln].l==i)

           {

               ans[q[ln].index]=getM(q[ln].r);

               ++ln;

           }

       }

       for(int i=0;i<Q;++i)

       printf("%d\n",ans[i]);

    }

    return 0;

}

 

你可能感兴趣的:(game)