zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    在游戏中充分利用可编程的GPU
    坐标变换
    深入理解GPU Architecture(上)
    RV870和GT300的一些猜测
    深入理解Intel Core Microarchitecture
    CGDC见闻
    hdu 1517 K(2~9)倍博弈
    hdu 2177 威佐夫博弈+输出使你胜的你第1次取石子后剩下的两堆石子的数量
    坚持住
    真正体会到一个ac的快感
  • 原文地址:https://www.cnblogs.com/liulangye/p/3228706.html
Copyright © 2011-2022 走看看