zoukankan      html  css  js  c++  java
  • 【数学 随机 技巧】cf364D. Ghd

    随机化选讲的例题

    John Doe offered his sister Jane Doe find the gcd of some set of numbers a.

    Gcd is a positive integer g, such that all number from the set are evenly divisible by g and there isn't such g(g' > g), that all numbers of the set are evenly divisible by g'.

    Unfortunately Jane couldn't cope with the task and John offered her to find the ghd of the same subset of numbers.

    Ghd is a positive integer g, such that at least half of numbers from the set are evenly divisible by g and there isn't such g(g' > g) that at least half of the numbers from the set are evenly divisible by g'.

    Jane coped with the task for two hours. Please try it, too.

    Input

    The first line contains an integer n (1 ≤ n ≤ 106) showing how many numbers are in set a. The second line contains space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 1012). Please note, that given set can contain equal numbers.

    Please, do not write the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the %I64d specifier.

    Output

    Print a single integer g — the Ghd of set a.


    题目分析

    随机化+复杂度分析

    首先按照随机化题的处理方式,随机选一个数$a_{pos}$钦定它在答案集合内。再考虑如何找出剩下数中满足条件的最大公因数。由于这个公因数一定是$d=gcd{a_{pos},a_i}$,并且所有$d|d'$的$d'$也都会算在$d$的贡献里。那么这里由复杂度分析的经验得,由于$10^{12}$内因数最多的数约有$7000$个约数,那么我们并不需要对$d$存下所有$d'$的贡献,而是每次暴力地累计答案即可。

    话说为什么这个srand(time(0))的随机化正确率这么低……只有选15个数才能擦着时限过去。

     1 #include<bits/stdc++.h>
     2 typedef long long ll;
     3 const int maxn = 1000035;
     4 
     5 int n;
     6 ll a[maxn],ans;
     7 std::map<ll, int> mp;
     8 std::map<ll, int>::iterator it,tmp;
     9 
    10 ll read()
    11 {
    12     char ch = getchar();
    13     ll num = 0;
    14     for (; !isdigit(ch); ch=getchar());
    15     for (; isdigit(ch); ch=getchar())
    16         num = (num<<1)+(num<<3)+ch-48;
    17     return num;
    18 }
    19 ll gcd(ll a, ll b){return !b?a:gcd(b, a%b);}
    20 int main()
    21 {
    22     srand(time(0)), n = read();
    23     for (int i=1; i<=n; i++) a[i] = read();
    24     for (int cse=15; cse; --cse)
    25     {
    26         mp.clear();
    27         int pos = 1ll*rand()*rand()%n+1;
    28         if (a[pos] <= ans) continue;
    29         for (int i=1; i<=n; i++)
    30         {
    31             ll val = gcd(a[pos], a[i]);
    32             if (val > ans) ++mp[val];
    33         }
    34         it = mp.end();
    35         for (int cnt; it!=mp.begin(); )
    36         {
    37             cnt = 0, --it;
    38             if ((*it).first <= ans) break;
    39             for (tmp=it; tmp!=mp.end(); ++tmp)
    40                 if (!((*tmp).first%(*it).first)) cnt += (*tmp).second;
    41             if (cnt >= (n+1)/2) ans = (*it).first;
    42         }
    43     }
    44     printf("%lld
    ",ans);
    45     return 0;
    46 }

    END

  • 相关阅读:
    linux内存不足导致java进程被kill掉
    记一次centos服务器DNS引起的网络问题
    记consul集群和spring cloud集成遇到的问题。
    记一次url未encode遇到的问题
    十六周总结
    十五周总结
    计算最长英语单词链
    大道至简阅读笔记02
    大道至简阅读笔记01
    用户体验评价之搜狗输入法
  • 原文地址:https://www.cnblogs.com/antiquality/p/10631545.html
Copyright © 2011-2022 走看看