• 所谓的日常 #2 張翼德怒鞭督郵 何國舅謀誅宦豎


    div.2

    CodeForces 567A Lineland Mail

    给定x轴上n(<=1e5)个点的坐标(从小到大),问每个点到其最近点和最远点的距离分别是多少。

    当然n ^ 2是不可以通过的...因为跑得太慢了。一般来讲,计算机1秒可以执行10的8次方左右的操作次数,而n^2 = 10的10次方...

    因为给出的数组已经是升序了,所以对于一个点来说,最近点一定是左边和右边临近的一个,最远点则是最左和最右中的一个。

     然后min函数和max函数在algorithm头文件里有。

     1 #include <stdio.h>
     2 #include <algorithm>
     3 
     4 const int N = 100000 + 5;
     5 int n,A[N];
     6 
     7 int main() {
     8     scanf("%d",&n);
     9     for (int i = 0; i < n; ++ i) {
    10         scanf("%d",A + i);
    11     }
    12     for (int i = 0; i < n; ++ i) {
    13         if (i == 0) {
    14             printf("%d %d\n",A[1] - A[0],A[n - 1] - A[0]);
    15         } else if (i == n - 1) {
    16             printf("%d %d\n",A[n - 1] - A[n - 2],A[n - 1] - A[0]);
    17         } else {
    18             printf("%d %d\n",std::min(A[i] - A[i - 1],A[i + 1] - A[i]),std::max(A[i] - A[0],A[n - 1] - A[i]));
    19         }
    20     }
    21 }
    View Code

    div.1

    CodeForces 364D Ghd

    给定n(<= 1e6)个整数(<= 1e12),找到一个最大的整数x,使得x是n个数中的至少一半数的约数。

    考虑这么一件事情,假如我们知道答案是x,那么从n个数里随机选出一个数y,x是y的约数的概率为1/2。

    那么随机选10次,x是这10个数中的至少一个数的约数的概率为(1 - 0.5^10) = 0.9990234375,基本认为必中。

    那么做法就是 随机K(K取10)次,每次从n个数中随机选出一个数,枚举它的全部约数,判断该约数是否出现了足够多次,是的话更新一下答案。

    然后我们知道一个整数A的约数数量约是O(log(A)^2)级别的,所以判断的部分平方枚举两个约数log(A)^4,千万级别。

    我实现的代码复杂度为O(K *  (sqrt(A) + nlog(log(A)^2) + log(A)^4)),大约2e8。

     1 #include <bits/stdc++.h>
     2 typedef long long LL;
     3 
     4 const int N = 1000000 + 5;
     5 LL A[N],B[N];
     6 int n,tot,cnt[N];
     7 
     8 LL gcd(LL a,LL b) {
     9     return b == 0 ? a : gcd(b,a % b);
    10 }
    11 
    12 LL work() {
    13     LL ret = 1;
    14     for (int step = 0; step < 10; ++ step) {
    15         LL val = A[(rand() << 15 | rand()) % n];
    16         tot = 0;
    17         for (LL i = 1; i * i <= val; ++ i) {
    18             if (val % i == 0) {
    19                 B[tot++] = i;
    20                 if (i != val / i) {
    21                     B[tot++] = val / i;
    22                 }
    23             }
    24         }
    25         std::sort(B,B + tot);
    26         std::fill(cnt,cnt + tot,0);
    27         for (int i = 0; i < n; ++ i) {
    28             cnt[std::lower_bound(B,B + tot,gcd(A[i],val)) - B] ++;
    29         }
    30         for (int i = tot - 1; i >= 0; -- i) {
    31             if (B[i] <= ret) break;
    32             int sum = 0;
    33             for (int j = i; j < tot; ++ j) {
    34                 if (B[j] % B[i] == 0)
    35                     sum += cnt[j];
    36             }
    37             if (sum * 2 >= n) {
    38                 ret = B[i];
    39             }
    40         }
    41     }
    42 
    43     return ret;
    44 }
    45 
    46 int main() {
    47     srand(time(NULL));
    48     scanf("%d",&n);
    49     for (int i = 0; i < n; ++ i) {
    50         scanf("%I64d",A + i);
    51     }
    52     printf("%I64d\n",work());
    53 }
    View Code
  • 相关阅读:
    HDU6168 Numbers
    HDU6170 Two strings
    UVA11426 GCD
    hihocoder1560 H国的身份证号码II
    HDU6156 Palindrome Function
    UVA10917 Walk Through the Forest
    UVA11374 Airport Express
    hihocoder1323 回文字符串
    hihocoder1543 SCI表示法
    CodeForces501C Misha and Forest
  • 原文地址:https://www.cnblogs.com/zstuACM/p/5058165.html
Copyright © 2020-2023  润新知