• SAC E#1


    题目背景

    SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友。

    题目描述

    SOL君很喜欢阶乘。而SOL菌很喜欢研究进制。

    这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘。

    SOL菌表示不服,立刻就要算这个数在k进制表示下末尾0的个数。

    但是SOL菌太菜了于是请你帮忙。

    输入输出格式

    输入格式:

    本题包含多组数据。

    每组输入仅包含一行:两个整数n,k。

    输出格式:

    对于每组输入,输出一个整数:n!在k进制下后缀0的个数。

    输入输出样例

    输入样例#1:
    10 40
    输出样例#1:
    2

    说明

    对于20%的数据,n <= 1000000, k = 10

    对于另外20%的数据,n <= 20, k <= 36

    对于60%的数据,n <= 10^15,k <= 10^12

    对于100%的数据,n <= 10^18,k <= 10^16

    鬼题

    如果k<=10^12是可以稳过的

    k<=10^16就只剩pollard Rho(超出提高组模拟范围了)或玄学优化

    首先k进制最后x位为0表示n!能整除k数x次(显然而重要的条件)

    于是问题变为了n!含有多少个k的因子

    k为合数不好处理,分解质因数k=p1^a1*p2^a2*p3^a3.....

    对于求n!含k的数量,转变为求p1....的因子数,在除以a1...,取最小值

    给出2种方法

    1.

    n!=(1k*2k*3k*4k*5k...mk)*a

    =k^m*m!*a

    a为不含k的积,m=n/k

    这样就可以log递归求解

    2.

    含有一个k:n/k

    含有二个k:n/k/k

    .....

    含有p个k:n/(k^p)

    把它们相加

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #define count COUNT
     7 using namespace std;
     8 long long prime[100001],mi[100001],tot;
     9 long long n,k,cnt,ans=9223372036854775807,s;
    10 long long count(long long p,long long k,long long Mod)
    11 {
    12   long long num=0,ss=0;
    13   while (p)
    14     {
    15       num+=p/k;
    16       if (num>=Mod) ss+=1,num-=Mod;
    17       p/=k;
    18     }
    19   return ss;
    20 }
    21 int main()
    22 {register long long i;
    23   while (scanf("%lld%lld",&n,&k)==2)
    24    {tot=0;ans=9223372036854775807;
    25   long long p=sqrt(k);
    26   for (i=2;i<=p;i++)
    27     {
    28       if (k%i==0)
    29     {
    30       prime[++tot]=i;
    31       cnt=0;
    32       while (k%i==0)
    33         {
    34           k/=i;
    35           cnt++;
    36         }
    37       mi[tot]=cnt;
    38     }
    39       if (k==1) break;
    40     }
    41   if (k!=1) 
    42     {tot++;
    43       prime[tot]=k;
    44       mi[tot]=1;
    45     }
    46   for (i=1;i<=tot;i++)
    47     {
    48       s=count(n,prime[i],mi[i]);
    49       if (ans>s) ans=s;
    50     }
    51   printf("%lld
    ",ans);
    52  }
    53 }
  • 相关阅读:
    【抄书笔记】《数据压缩导论》
    【举个栗子】我对BP算法的理解
    【举个栗子】我对支持向量机的理解
    linux中监控oracle alert 文件中的ORA-xxx报错信息并发邮件perl脚本
    从dba_hist_sqlstat视图中查找过去时段最占用资源的会话
    AWR信息导出
    Oracle表变化趋势追踪记录 & 表历史 统计信息查看
    oracle-database-maa-best-practices
    详解 db file sequential read 等待事件
    oracle性能优化:Linux环境下合理配置大内存页(HugePage)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7634964.html
Copyright © 2020-2023  润新知