zoukankan      html  css  js  c++  java
  • 所谓的日常 #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
  • 相关阅读:
    mysql修改数据表名
    HDU 5742 It's All In The Mind (贪心)
    HDU 5752 Sqrt Bo (数论)
    HDU 5753 Permutation Bo (推导 or 打表找规律)
    HDU 5762 Teacher Bo (暴力)
    HDU 5754 Life Winner Bo (博弈)
    CodeForces 455C Civilization (并查集+树的直径)
    CodeForces 455B A Lot of Games (博弈论)
    CodeForces 455A Boredom (DP)
    HDU 4861 Couple doubi (数论 or 打表找规律)
  • 原文地址:https://www.cnblogs.com/zstuACM/p/5058165.html
Copyright © 2011-2022 走看看