zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    zoj 2316 Matrix Multiplication 解题报告
    BestCoder7 1001 Little Pony and Permutation(hdu 4985) 解题报告
    codeforces 463C. Gargari and Bishops 解题报告
    codeforces 463B Caisa and Pylons 解题报告
    codeforces 463A Caisa and Sugar 解题报告
    CSS3新的字体尺寸单位rem
    CSS中文字体对照表
    引用外部CSS的link和import方式的分析与比较
    CSS样式表引用方式
    10个CSS简写/优化技巧
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3989065.html
Copyright © 2011-2022 走看看