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
",ans[i]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/liulangye/p/3228706.html