zoukankan      html  css  js  c++  java
  • bzoj 3837 (随机过题法了解一下)

    3837: [Pa2013]Filary

    Time Limit: 60 Sec  Memory Limit: 256 MB
    Submit: 395  Solved: 74
    [Submit][Status][Discuss]

    Description

    给定n个正整数,从中挑出k个数,满足:存在某一个m(m>=2),使得这k个数模m的余数相等。
     
    求出k的最大值,并求出此时的m。如果有多组解使得k最大,你要在此基础上求出m的最大值。
     
    
    
    

    Input

    第一行一个正整数n(2<=n<=10^5)。
     
    第二行n个正整数w[i](1<=w[i]<=10^7)。保证不会出现所有w[i]都相等的情况。
     

    Output

    一行两个整数k,m。保证答案存在。
     

    Sample Input

    6
    7 4 10 8 7 1

    Sample Output

    5 3

    HINT


    听说大家都喜欢随机过题法,于是我切一道(正解是)随机的题目涨涨姿势。
    首先此题在k==2 的时候最小是 $ frac{n}{2} $ 的,以此类推 k==3 时是 $ frac{n}{3} $等等。
    那么最小的情况是大于等于$ frac{n}{2} $的,这点毋庸置疑。
    那么我们随机一个位置pos,假设a[pos]在这k个数中,找最大的k。
    那么我们求a[pos]和每个位置i的差值b[i],然后我们这k个数的 $ gcd gt 1 $ 这个毋庸置疑。那么我们把每个b[i]分解成一堆质数,并记录每个质数出现的位置数。那么最大的k就是质数出现的最大位置数。k对应的最大的m就是这些位置的数的gcd。
    而据cls说这个随机期望是logn的。不过你还是多随机个四五次取最大,这样才保险点。
     1 #include<bits/stdc++.h>
     2 #define clr(x) memset(x,0,sizeof(x))
     3 #define clr_1(x) memset(x,-1,sizeof(x))
     4 #define INF 0x3f3f3f3f
     5 #define LL long long
     6 #define pb push_back
     7 #define mod 1000000007
     8 #define ls(i) (i<<1)
     9 #define rs(i) (i<<1|1)
    10 #define mp make_pair
    11 #define fi first
    12 #define se second
    13 using namespace std;
    14 const int N=1e7+10;
    15 const int M=1e5+10;
    16 int inf[N],prime[N],pre[N],g[N],num[N];
    17 int tot;
    18 int gcd(int a,int b)
    19 {
    20     int c;
    21     while(b)
    22         c=a%b,a=b,b=c;
    23     return a;
    24 }
    25 void init()
    26 {
    27     tot=0;
    28     int n=10000000;
    29     for(int i=2;i<=n;i++)
    30     {
    31         if(!inf[i])
    32             prime[++tot]=i,pre[i]=tot;
    33         for(int j=1;j<=tot && prime[j]*i<=n;j++)
    34         {
    35             inf[prime[j]*i]=1;
    36             pre[prime[j]*i]=j;
    37             if(i%prime[j]==0) break;
    38         }
    39     }
    40     return ;
    41 }
    42 int a[M],b[M];
    43 int main()
    44 {
    45     init();
    46     int n,m,k;
    47     scanf("%d",&n);
    48     for(int i=1;i<=n;i++)
    49         scanf("%d",a+i);
    50     int p=log10(n)+5;
    51     srand(time(0));
    52     m=k=0;
    53     while(p--)
    54     {
    55 
    56         int pos=rand()%n+1;
    57         int tmp=0;
    58         int minm=0,mink=0;
    59         for(int i=1;i<=n;i++)
    60         {
    61             b[i]=abs(a[i]-a[pos]);
    62             if(!b[i])
    63                 tmp++;
    64         }
    65         for(int i=1;i<=n;i++)
    66         {
    67             int t=b[i];
    68             while(t && t!=1)
    69             {
    70                 int temp=pre[t];
    71                 num[temp]++,g[temp]=gcd(g[temp],b[i]);
    72                 if(mink<num[temp]) mink=num[temp],minm=g[temp];
    73                 else if(mink==num[temp]) minm=max(g[temp],minm);
    74                 while(t%prime[temp]==0) t/=prime[temp];
    75             }
    76         }
    77         if(mink+tmp>k) k=mink+tmp,m=minm;
    78         else if(mink+tmp==k) m=max(m,minm);
    79         for(int i=1;i<=n;i++)
    80         {
    81             int t=b[i];
    82             while(t && t!=1)
    83             {
    84                 int temp=pre[t];
    85                 num[temp]=0,g[temp]=0;
    86                 while(t%prime[temp]==0) t/=prime[temp];
    87             }
    88         }
    89     }
    90     printf("%d %d
    ",k,m);
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    m.baidu.com/?tn=simple 开始有广告了。。。
    一些话
    sublime text3中如何使用PHP编译系统
    遇到了一个特别有意思的题
    RVS PA-1800 功放参数
    TP框架修改后台路径方法
    换手机号之前需要看看
    layui跨域问题的解决
    Send me
    单细胞文章分享:Molecular Diversity of Midbrain Development in Mouse, Human, and Stem Cells
  • 原文地址:https://www.cnblogs.com/wujiechao/p/9188843.html
Copyright © 2011-2022 走看看