您的位置:首页 > 其它

[51Nod 1224] 阶乘的幂的倍数

2016-03-04 23:31 453 查看


题解:注意到 f(i, k) 一定单调, 从小到大枚举每一个 i , 分解素数可以求出此时满足条件的最小的 N …… 看代码把 ಥ_ಥ …… 不会证明复杂度…. n 乘若干个 log ? hhhhhhhh

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const int mo = 1e9 + 7;
const int N = 1e6 + 10;

int prime
, minn
, cnt;
bool vis
;

void prepare(int n)
{
minn[1] = 1;
for (int i = 2; i <= n; ++i)
{
if (!vis[i]) prime[++cnt] = minn[i] = i;
for (int j = 1; j <= cnt; ++j)
{
int to = prime[j] * i;
if (to > n) break;
vis[to] = 1, minn[to] = prime[j];
if (i % prime[j] == 0) break;
}
}
}

int n; LL k;
LL sum, now = 1;

LL getNum(LL x, int p)
{
LL ret = 0;
while (x) ret += (x /= p);
return ret;
}

LL C
, Pow[60], Stk[60];
void addPrime(int x, LL c)
{
C[x] += c;
if (getNum(now, x) < C[x])
{
LL tmp = C[x];
int l = -1;
while (Stk[++l] < C[x])
{
Pow[l + 1] = Pow[l] * x;
Stk[l + 1] = Stk[l] + Pow[l];
}
for (now = 0; l; --l) if (tmp >= Stk[l])
{
LL q = tmp / Stk[l];
now += Pow[l] * q;
tmp -= Stk[l] * q;
}
}
}

void insert(int x)
{
while (x > 1)
{
int tmp = minn[x], cnt = 0;
while (minn[x] == tmp) x /= tmp, cnt++;
addPrime(tmp, k * cnt);
}
}

int main()
{
scanf("%d%lld", &n, &k);
prepare(n), Pow[0] = 1;
for (int i = 2; i <= n; ++i)
{
insert(i);
sum = (sum + now) % mo;
}
printf("%lld\n", sum);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: