• CodeForces


    一道通过预处理使得无需使用lower_bound的题,最终的复杂度是O(MlogN),也算是对调和复杂度分析的一个练习吧

    题意:给定不超过n(1<=n<=200000)个数,每个数介于1~1e6之间,选定两个数使得ai%aj最大

    思路:对于一个值aj,我们要找到ai使ans=ai%aj最大,ans显然小于aj。我们希望ans越大,就要求ai越靠近且略小于aj的倍数。由于给出的数列的值是有上界的,我们对于从[aj, aj + aj)开始的每段区间长度为aj的段,找出那个最大的数,然后更新ans的值即可。问题在于如何找到那个最大的数?第一反应可能会想到先对数组进行排序,然后再利用lower_bound进行二分搜索。这样以来复杂度是(NlogN + MlogMlogN),可不可以卡过没有尝试过。

      但是重点在与,我们对于每个不大于2*上界的值,我们可以预处理出给定的数列里不大于它的最大值,这个过程只需要O(M)就可以实现了,这样以来,查询过程的复杂度就是O(1),总的复杂度就是O(MlogN)了,强无敌啊。

      我开了两个数组,pre[i]用于记录题目给定数列中小于i的最大值,a[i]用于记录i是否在原数列中出现过。枚举所有值不同的aj,去更新ans。最多N个aj,每个在第二层循环运行(2 * 上界 / aj) - 1次,那就约为一个上界*调和级数的复杂度。最坏情况下,(1+1/2+1/3+...+1/N),调和级数的值为log(N) + C(欧拉常数),所以总的复杂度是O(MlogN)

     1 #include <queue>
     2 #include <vector>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <iostream>
     6 #include <algorithm>
     7 #define INF 0x3f3f3f3f
     8 #define MOD 1000000007
     9 using namespace std;
    10 typedef long long LL;
    11 
    12 const int maxm = 1e6;
    13 int pre[maxm * 2 + 10];
    14 bool a[maxm + 10];
    15 int N;
    16 
    17 
    18 int main(int argc, const char * argv[]) {
    19     scanf("%d", &N);
    20     for (int i = 1; i <= N; i++) {
    21         int val;
    22         scanf("%d", &val);
    23         pre[val] = -1;
    24         a[val] = true;
    25     }
    26     //预处理
    27     int small = 0;
    28     int big = small;
    29     while (big <= maxm * 2) {
    30         while (big <= maxm * 2 && pre[big] != -1) {
    31             big++;
    32         }
    33         for (int i = small + 1; i <= big; i++) {
    34             pre[i] = small;
    35         }
    36         small = big;
    37     }
    38     
    39     int ans = 0;
    40     for (int i = 1; i <= maxm; i++) {
    41         if (!a[i]) continue;
    42         for (int j = i + i; j <= maxm * 2; j += i) {
    43             ans = max(ans, pre[j] % i);
    44         }
    45     }
    46     printf("%d
    ", ans);
    47     return 0;
    48 }
    View Code
  • 相关阅读:
    codeforces C. No to Palindromes!
    codeforces D. Pashmak and Parmida's problem
    codeforces C. Little Pony and Expected Maximum
    codeforces D. Count Good Substrings
    codeforces C. Jzzhu and Chocolate
    codeforces C. DZY Loves Sequences
    codeforces D. Multiplication Table
    codeforces C. Painting Fence
    hdu 5067 Harry And Dig Machine
    POJ 1159 Palindrome
  • 原文地址:https://www.cnblogs.com/xFANx/p/7324712.html
Copyright © 2020-2023  润新知