• Codeforces C. Maximum Value(枚举二分)


    题目描述:

    Maximum Value

    time limit per test

    1 second

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    You are given a sequence a consisting of n integers. Find the maximum possible value of img (integer remainder of a**i divided by a**j), where 1 ≤ i, j ≤ n and a**i ≥ a**j.

    Input

    The first line contains integer n — the length of the sequence (1 ≤ n ≤ 2·105).

    The second line contains n space-separated integers a**i (1 ≤ a**i ≤ 106).

    Output

    Print the answer to the problem.

    Examples

    Input

    Copy

    33 4 5
    

    Output

    Copy

    2
    

    思路:

    题目是说,给一个数列,求这个数列的任两个数中大数模小数的最大值。先说说正确的思路,考虑每个数,枚举它的倍数,在数列中每次二分查找比这个倍数大于等于的数的位置,减一后就是这个数被数列中的数模得到最大值的位置。具体的,a[i]来说,我们每次枚举a[i]的倍数,发现([a[i]*k,a[i]*(k+1))),在这个区间内一个数模a[i]值是递增的。那么数列中最接近(a[i]*(k+1))的数来%a[i]就可以得到最大值。这个数怎么求呢?具体的,就是lower_bound找到大于等于([i]*(k+1))的值的位置减一。为什么减一,加入数列中刚好有(a[i]*(k-1)),我们减一就得到最接近它的数,如果没有,减一也得到了最接近它的数。注意题目要求要大数模小数。

    再来说说一个看着正确的思路。转化研究对象我们来看对数列中的每一个数,怎么才能让它的余数最大。

    比如:9,9%2=1,%3=0,%4=1,%5=4,%6=3,%7=2,%8=1我们发现,当它模自己一半左右的数时取得模的最大值。这个思路就是在数组中二分查找一个数一半的值,在一半的值的位置附近遍历找最大。这个只能过12个测试点,好像。原因呢,可不可以构造出一组数据,让一个数的一半左右的值都不在遍历范围,然后取到不是最大值的数刚刚好在遍历范围内呢?暂时不知道,留待解答。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define max_n 200005
    using namespace std;
    int n;
    int a[max_n];
    int tot = 0;
    int cnt[1000005];
    int maxm = 0;
    inline void read(int& x)
    {
        x=0;int f=0;char ch = getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')f=1;ch=getchar();}
        while('0'<=ch&&ch<='9') {x=10*x+ch-'0';ch=getchar();}
        x=f?-x:x;
    }
    #pragma optimize(2)
    int main()
    {
        read(n);
        for(int i = 0;i<n;i++)
        {
            int num;
            read(num);
            if(cnt[num]==0)
            {
                a[tot++] = num;
                cnt[num] = 1;
            }
        }
        sort(a,a+tot);
        for(int i = 0;i<tot;i++)
        {
            for(int j = a[i];j<=2*a[tot-1];j+=a[i])
            {
                int pos = lower_bound(a,a+tot,j+a[i])-a-1;
                if(pos==-1)pos++;
                //cout << "pos " << pos << endl;
                //cout << a[pos] << "%" << a[i] << endl;
                maxm = max(maxm,a[pos]%a[i]);
            }
        }
        cout << maxm << endl;
        return 0;
    }
    
    

    参考文章:

    张松超,codeforces 485D. Maximum Value(二分+思维),https://blog.csdn.net/ZscDst/article/details/78775965

  • 相关阅读:
    Rest_framework-3
    Nginx 之一:编译安装nginx 1.8.1 及配置
    vmware虚拟机克隆CentOS7 出现的网络问题解决办法
    OAuth认证
    5个节点hadoop安装(zookeeper)
    hadoop完整安装
    从vmware模板克隆linux的操作
    ssh 免密码设置失败原因总结
    hadoop-2.6.0.tar.gz的集群搭建(3节点)(不含zookeeper集群安装)
    linux静态IP设置
  • 原文地址:https://www.cnblogs.com/zhanhonhao/p/11308325.html
Copyright © 2020-2023  润新知