zoukankan      html  css  js  c++  java
  • 数值距离

    题目描述
    我们可以对一个数进行两种操作,即把一个数乘上一个质数或者除以一个质
    数。我们定义两个数 a,b 之间的距离为把 a 变成 b 需要执行的最少操作次数,例
    如 d(69,42)=3,因为 42=69/23*2*7。
    我们给出一个长度为 n 的序列 a 1 ,a 2 ,...,a n ,对于每一个 a i 我们需要找到一个
    不等于 i 的最小的 j 使得 a i 和 a j 的距离是最小的。
    输入格式
    第一行一个整数 n。
    接下来 n 行,第 i 行一个整数 a i 。
    输出格式
    n 行,第 i 行一个整数,表示 d(ai,aj)最小时最小的 j。
    输入样例
    6
    1
    2
    3
    4
    5
    6
    输出样例
    2
    1
    1
    2
    1
    2

    数据规模
    30%的数据,n<=1000。
    另外 20%的数据,a i <=1000。
    100%的数据,2<=n<=100000,1<=a i <=1000000。

    我们看到ai<=1000000,正常情况下,如果复杂度与a没关系应该是10^9

    考虑以ai为点建图,如果两个数可以通过一次变换就建边

    用ai做起点,如果ai为起点的路径碰上了以aj为起点的路径,那么就要更新ai和aj的答案

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 typedef long long lol;
     9 lol n;
    10 lol vis[1000001],v[1000001],dist[1000001],tot,Min[1000001],pos[1000001],a[1000001],pre[1000001],prime[1000001];
    11 void zyys(int x,int y)
    12 {
    13     if (v[x]==v[y]) return;
    14     int now=dist[x]+dist[y]+1;
    15     if (Min[v[x]]==now) pos[v[x]]=min(pos[v[x]],v[y]);
    16     if (Min[v[y]]==now) pos[v[y]]=min(pos[v[y]],v[x]);
    17     if (Min[v[x]]>now) Min[v[x]]=now,pos[v[x]]=v[y];
    18     if (Min[v[y]]>now) Min[v[y]]=now,pos[v[y]]=v[x];
    19     if (dist[x]==dist[y]+1)
    20         v[x]=min(v[x],v[y]);
    21 }
    22 void SPFA()
    23 {
    24     int i;
    25     queue<int>Q;
    26     memset(dist,127/2,sizeof(dist));
    27     for (i=1; i<=n; i++)
    28     {
    29         if (v[a[i]]==i) Q.push(a[i]);
    30     }
    31     while (Q.empty()==0)
    32     {
    33         int u=Q.front();
    34         Q.pop();
    35         int b=u;
    36         while (b!=1)
    37         {
    38             int now=u/pre[b];
    39             if (v[now]==0) v[now]=v[u],dist[now]=dist[u]+1,Q.push(now);
    40             else zyys(now,u);
    41             b/=pre[b];
    42         }
    43         for (i=1; i<=tot&&1ll*u*prime[i]<=1000000; i++)
    44         {
    45             int now=u*prime[i];
    46             if (v[now]==0) v[now]=v[u],dist[now]=dist[u]+1,Q.push(now);
    47             else zyys(now,u);
    48         }
    49     }
    50 }
    51 int main()
    52 {
    53     lol i,j,d,ans;   56     cin>>n;
    57     vis[1]=1;
    58     for (i=2; i<=1000000; i++)
    59     {
    60         if (vis[i]==0)
    61         {
    62             ++tot;
    63             prime[tot]=i;
    64             pre[i]=i;
    65         }
    66         for (j=1; j<=tot; j++)
    67         {
    68             if (1ll*i*prime[j]>1000000) break;
    69             vis[i*prime[j]]=1;
    70             pre[i*prime[j]]=prime[j];
    71             if (i%prime[j]==0) break;
    72         }
    73     }
    74     memset(Min,127/2,sizeof(Min));
    75     memset(pos,127/2,sizeof(pos));
    76     for (i=1; i<=n; i++)
    77     {
    78         scanf("%lld",&a[i]);
    79         if (v[a[i]]==0) v[a[i]]=i;
    80         else
    81         {
    82             Min[i]=Min[v[a[i]]]=0;
    83             pos[i]=min(pos[i],v[a[i]]);
    84             pos[v[a[i]]]=min(pos[v[a[i]]],i);
    85         }
    86     }
    87     SPFA();
    88     for (i=1; i<=n; i++)
    89         printf("%lld
    ",pos[i]);
    90 }
  • 相关阅读:
    CSS实现水平居中的5种思路
    html5遵循的5个设计原则
    HTML5标签嵌套规则
    动画animation的三个应用(漂浮的白云、旋转的星球、正方体合成)
    深入理解CSS动画animation
    深入理解CSS径向渐变radial-gradient
    深入理解CSS线性渐变linear-gradient
    动态更新语句,时间精度丢失
    反射类的构造数
    在ASP.NET MVC中使用Grid.mvc
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8602374.html
Copyright © 2011-2022 走看看