zoukankan      html  css  js  c++  java
  • [BZOJ2790][Poi2012]Distance

    2790: [Poi2012]Distance

    Time Limit: 40 Sec  Memory Limit: 128 MB
    Submit: 225  Solved: 115
    [Submit][Status][Discuss]

    Description

     

     

    对于两个正整数a、b,这样定义函数d(a,b):每次操作可以选择一个质数p,将a变成a*p或a/p,

    如果选择变成a/p就要保证p是a的约数,d(a,b)表示将a变成b所需的最少操作次数。例如d(69,42)=3。

    现在给出n个正整数A1,A2,...,An,对于每个i (1<=i<=n),求最小的j(1<=j<=n)使得i≠j且d(Ai,Aj)最小。

     

     

    Input

    第一行一个正整数n (2<=n<=100,000)。第二行n个正整数A1,A2,...,An (Ai<=1,000,000)。

     

     

     

    Output

    输出n行,依次表示答案。

     

     

     

    Sample Input

    6
    1
    2
    3
    4
    5
    6

    Sample Output

    2
    1
    1
    2
    1
    2

    HINT

     

    Source

    [Submit][Status][Discuss]

    很容易推出来 $d(x,y)=g(x)+g(y)-2*g(gcd(x,y))$ 其中g(x)表示x是几个质数的乘积

    $g$函数只需要一个线性筛就能求出来,对于$a_i$,$g(a_i)$是固定的,重点在于最小化$g(y)-2*g(gcd(x,y))$

    可以枚举$a_i$的因子$x$,用$f[x]$表示是$x$的倍数的$a[j]$使得$g[a[j]]$最小的数

    因为要求$i≠j$,所以得维护最小值和次小值,时间复杂度$O(nsqrt m+m)$ $m=max{a_i}$

    PS:今天BZOJ居然卡住了,管理员今天不在吗?

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define N 100010
     6 #define M 1000010
     7 int prime[M],tot,g[M];
     8 inline void pre(int t)
     9 {
    10     g[0]=1e9;
    11     for(int i=2;i<=t;i++)
    12     {
    13         if(!g[i])prime[++tot]=i,g[i]=1;
    14         for(int j=1;j<=tot&&i*prime[j]<=t;j++)
    15         {
    16             g[i*prime[j]]=g[i]+1;
    17             if(!(i%prime[j]))break;
    18         }
    19     }
    20 }
    21 int n,a[N],f[M][2],maxn;
    22 inline void update(int x,int i)
    23 {
    24     if(g[a[x]]<=g[a[f[i][0]]])
    25     f[i][1]=f[i][0],f[i][0]=x;
    26     else if(g[a[x]]<=g[a[f[i][1]]])
    27     f[i][1]=x;
    28 }
    29 int main()
    30 {
    31     scanf("%d",&n);
    32     for(int i=1;i<=n;i++)
    33     scanf("%d",&a[i]),maxn=max(a[i],maxn);
    34     pre(maxn);
    35     for(int i=n;i;i--)
    36     {
    37         for(int j=1;j*j<=a[i];j++)
    38         if(!(a[i]%j))
    39         {
    40             update(i,j);
    41             if(j*j!=a[i])
    42             update(i,a[i]/j);
    43         }
    44     }
    45     for(int i=1;i<=n;i++)
    46     {
    47         int ans=1e9,tmp=1e9;
    48         for(int j=1;j*j<=a[i];j++)
    49         if(!(a[i]%j))
    50         {
    51             int k=j,x;
    52             if(f[k][0]!=i)x=f[k][0];
    53             else x=f[k][1];
    54             int t=g[a[x]]-2*g[k];
    55             if(t<ans||(t==ans&&x<tmp))
    56             ans=t,tmp=x;
    57             k=a[i]/j;            
    58             if(f[k][0]!=i)x=f[k][0];
    59             else x=f[k][1];
    60             t=g[a[x]]-2*g[k];
    61             if(t<ans||(t==ans&&x<tmp))
    62             ans=t,tmp=x;
    63         }
    64         printf("%d
    ",tmp);
    65     }
    66 }
    View Code
    就让我永远不在这里写什么有意义的话--月下孤狼
  • 相关阅读:
    CCNP-MPLS-标签交换
    Mac地址表、STP与RSTP原理
    mysql 初始数据库简单操作
    异步回调,事件,线程池与协程
    bug问题
    GIL 线程池
    异常处理
    奇怪的东西
    绑定方法
    初体验
  • 原文地址:https://www.cnblogs.com/xuruifan/p/5188715.html
Copyright © 2011-2022 走看看