2020 China Collegiate Qinhuangdao Site G. Good Number(分段算贡献)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020 China Collegiate Qinhuangdao Site G. Good Number(分段算贡献)相关的知识,希望对你有一定的参考价值。
定义数字 x x x是好数,有 ⌊ k x ⌋ \\lfloor ^k\\sqrt{x} \\rfloor ⌊kx⌋是 x x x的因子
求 [ 1 , n ] [1,n] [1,n]中有多少个好数字
当 k = 1 k=1 k=1时答案显然是 n n n
否则
考虑 ⌊ k x ⌋ \\lfloor ^k\\sqrt{x} \\rfloor ⌊kx⌋的取值范围
最坏情况下 k = 2 k=2 k=2,而 1 0 9 < 1 0 5 \\sqrt{10^9}<10^5 109<105
随意我们完全可以枚举 ⌊ k x ⌋ \\lfloor ^k\\sqrt{x} \\rfloor ⌊kx⌋的值
我们知道 1 k = 1 1^k=1 1k=1,所以 1 1 1对应的 ⌊ k x ⌋ \\lfloor ^k\\sqrt{x} \\rfloor ⌊kx⌋就是 1 1 1
我们也可以计算出 2 k 2^k 2k,显然 2 k 2^k 2k对应的 ⌊ k x ⌋ \\lfloor ^k\\sqrt{x} \\rfloor ⌊kx⌋就是 2 2 2
所以我们得到区间 [ 1 , 2 k − 1 ] [1,2^k-1] [1,2k−1]对应的 ⌊ k x ⌋ \\lfloor ^k\\sqrt{x} \\rfloor ⌊kx⌋是 1 1 1
区间 [ 2 k , 3 k − 1 ] [2^k,3^k-1] [2k,3k−1]对应的 ⌊ k x ⌋ \\lfloor ^k\\sqrt{x} \\rfloor ⌊kx⌋是 2 2 2
以此类推,计算这个区间内的贡献即可
注意计算 i k i^k ik时候手算,不然会爆 l o n g l o n g long\\ long long long
#include <bits/stdc++.h>
using namespace std;
#define int long long
int t,n,k,casenum;
int get(int l,int r,int k)
{
return r/k - (l-1)/k;
}
signed main()
{
cin >> t;
while( t-- )
{
cin >> n >> k;
cout << "Case #" << ++casenum << ": ";
if( k==1 ) cout << n << endl;
else
{
int ans = 0, las = 1;
for(int i=2;i<=n;i++)
{
int now = 1;
//手动计算i^k放置爆long long
for(int j=1;j<=k&&now<=n;j++) now *= i;
ans += get(las,min(n,now-1),i-1);
las = now;
if( las>n ) break;
}
cout << ans << endl;
}
}
}
以上是关于2020 China Collegiate Qinhuangdao Site G. Good Number(分段算贡献)的主要内容,如果未能解决你的问题,请参考以下文章
2020 China Collegiate Programming Contest, Weihai Site L. Clock Master(分组背包)
2020 China Collegiate Qinhuangdao Site F. Friendly Group(思维+边双连通)
2020 China Collegiate Programming Contest - Mianyang Site J. Joy of Handcraft(线段树模板)
2020 China Collegiate Programming Contest, Weihai Site C. Rencontre(lca+树形dp)
The 2019 China Collegiate Programming Contest Harbin Site
The 2019 China Collegiate Programming Contest Harbin Site F. Fixing Banners