• HDU 4630 No Pain No Game 树状数组+离线操作


    题意:给一串数字,每次查询[L,R]中两个数的gcd的最大值。

    解法:容易知道,要使取两个数让gcd最大,这两个数最好是倍数关系,所以处理出每个数的所有倍数,两两间根据倍数关系形成一条线段,值为该数。那么每次查询[L,R]之间两数gcd的最大值即为查询[L,R]中值最大的线段,离线所有的查询数据,然后按右端点坐标从小到大排序,依次往右加入即可。

    这里学到了树状数组维护最大值的写法。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 50007
    
    int c[N];
    struct node
    {
        int l,r,v;
    }a[10*N],Q[N];
    int n,pos[N],num[N],ans[N];
    
    int cmp(node ka,node kb) { return ka.r < kb.r; }
    int lowbit(int x) { return x&-x; }
    
    void modify(int x,int val)
    {
        while(x > 0)
        {
            c[x] = max(c[x],val);
            x -= lowbit(x);
        }
    }
    
    int getmax(int x)
    {
        int res = 0;
        while(x <= n)
        {
            res = max(res,c[x]);
            x += lowbit(x);
        }
        return res;
    }
    
    int main()
    {
        int t,i,j,x,q,tot;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(i=1;i<=n;i++)
            {
                scanf("%d",&x);
                pos[x] = i;
                c[i] = 1;
            }
            tot = 0;
            for(i=2;i<=n/2;i++)
            {
                int k = 0;
                for(j=i;j<=n;j+=i)  //i的倍数
                    num[k++] = pos[j];
                sort(num,num+k);
                for(j=1;j<k;j++)
                {
                     a[tot].l = num[j-1];
                     a[tot].r = num[j];
                     a[tot++].v = i;
                }
            }
            scanf("%d",&q);
            for(i=0;i<q;i++)
            {
                scanf("%d%d",&Q[i].l,&Q[i].r);
                Q[i].v = i;
            }
            sort(a,a+tot,cmp);
            sort(Q,Q+q,cmp);
            j = 0;
            for(i=0;i<q;i++)
            {
                if(Q[i].l == Q[i].r)
                {
                    ans[Q[i].v] = 0;
                    continue;
                }
                while(j < tot && a[j].r <= Q[i].r)
                    modify(a[j].l,a[j].v),j++;
                ans[Q[i].v] = getmax(Q[i].l);
            }
            for(i=0;i<q;i++)
                printf("%d
    ",ans[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Servlet 的生命周期
    关于JSP
    JQuery事件绑定
    JavaScript中操作元素
    javaScript的函数使用
    Servlet 的API
    JavaScript中BOM对象
    gridview 绑定时间列 取短日期
    A4纸网页打印中对应像素的设定和换算
    动态添加 控件 并获取值
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3989065.html
Copyright © 2020-2023  润新知