zoukankan      html  css  js  c++  java
  • 【数位贪心】loj#530. 「LibreOJ β Round #5」最小倍数

    记录一下题解里写的算法四

    题目描述

    $1 le T le 10^4,1le mle 100,0le a_ile 10^{18}$.


    题目分析

    题解里的算法四是这么写的

    主要是这个$alpha_i = sum_{k = 1}^{infty}{left lfloor frac{N}{mathrm{pr}_i^k} ight floor}$的计算在蛮多地方有看到应用,所以这里记一下对算法四的理解。

    题目给了$m$个$e_i$的限制,要求满足$alpha_i ge e_i$.首先由于这$m$个限制之间互相并不影响,所以答案$N=max{N_i}$,其中$N_i$表示最小的满足第$i$个限制的数。这样只需要来考虑如下问题:

    给定$alpha,e,质数p$,求最小的$N$满足$sum_{k = 1}^{infty}{left lfloor frac{N}{mathrm{p}^k} ight floor}=e$.

    比较常见的套路是把$N$按$p$进制拆分成$(x_1 x_2 cdots x_m)_{p}$。接下去考虑一个从右往左第$k+1$位$v cdot mathrm{p}^k$对$e$的贡献,由于它会在$k=1cdots mathrm{p}^k$时被计入,所以是$(v v cdots v)_{mathrm{p}}$(k个v).注意到这相当于是一个类似进制拆分的过程,那么就可以从高位到低位贪心地计算$N_i$。

     1 #include<bits/stdc++.h>
     2 typedef long long ll;
     3 typedef unsigned long long ull;
     4 
     5 int T;
     6 bool vis[10035];
     7 ll m,pr[103],ans;
     8 
     9 ll read()
    10 {
    11     char ch = getchar();
    12     ll num = 0, fl = 1;
    13     for (; !isdigit(ch); ch=getchar())
    14         if (ch=='-') fl = -1;
    15     for (; isdigit(ch); ch=getchar())
    16         num = (num<<1)+(num<<3)+ch-48;
    17     return num*fl;
    18 }
    19 void makePrime()
    20 {
    21     for (int i=2; i<=1000; i++)
    22     {
    23         if (!vis[i]) pr[++pr[0]] = i;
    24         if (pr[0]==100) break;
    25         for (int j=2; j*i<=1000; j++)
    26             vis[i*j] = true;
    27     }
    28 }
    29 void write(ll x){if (x/10) write(x/10);putchar(x%10+'0');}
    30 int main()
    31 {
    32     makePrime();
    33     for (T=read(); T; --T)
    34     {
    35         m = read(), ans = 1;
    36         for (int i=1; i<=m; i++)
    37         {
    38             ll e = read(), cnt = 0, base = 1, val = pr[i], p = pr[i];
    39             while (base*p+1 <= e)
    40                 base = base*p+1, val *= p;
    41             for (; base; base/=p,val/=p)
    42                 cnt += val*(e/base), e -= base*(e/base);
    43             ans = std::max(ans, cnt);
    44         }
    45         write(ans), putchar('
    ');
    46     }
    47     return 0;
    48 }

    END

  • 相关阅读:
    壶公随感
    消息称微软受谷歌刺激 急于收购雅虎(zz)
    远程注销Windows用户
    "杀人"游戏中的一些规律
    由两点的经纬度估算距离
    我的城市?
    Blog里的一个bug,dudu看能否修正?
    这两天真烦
    发简历,找上海.Net方面软件开发工作
    "上海.NET俱乐部"聚会筹备进展
  • 原文地址:https://www.cnblogs.com/antiquality/p/11747401.html
Copyright © 2011-2022 走看看