数理論はループに対してのみ可能です(数学+ブロック+記憶)

トピックリンク:ここをクリック

トピックの主なアイデア:
与えられたn、kn、kn k计計算関数数:
f(n、k)= {1 if k = 0 ∑ i =1n⌈log2i⌉f(⌊ni⌋、k − 1)ifk≥1f(n、k)= \ begin {cases} 1&if \ k = 0 \\ \ sum_ {i = 1} ^ n \ lceil log_2i \ rceil f(\ lfloor \ frac ni \ rfloor、k-1)&if \ k \ ge 1 \ end {cases}f n k ={{ 1i = 1n個L O G2F n個k1 i f k =0i f k 1
答えは1e 9 + 7 1e9 +7です1 e 9+7モジュロ

問題分析:
この式を分析すると、f(1、k)= 0(k≥1)f(1、k)= 0(k \ ge 1)であることが明らかです。f 1 k =0 k1 f(⌊ni⌋、k − 1)f(\ lfloor \ frac ni \ rfloor、k- 1
を見つけますf n個k1) 中的 ⌊ n i ⌋ \lfloor \frac ni \rfloor n個は典型的なブロックタイプであり、ブロックで処理できます。⌊ni⌋= 1 \ lfloor \ frac ni \ rfloor = 1n個=1このブロックサイズはn2 \ fracn2です。2n個、このプロパティを使用すると、f(n、k)f(n、k)を取得できます。f n k inf(1、x)f(1、x)f 1 x はおよそlog 2 nlog_2nですl o g2n(調和系列)
したがって、n≥log2(1 e 8)≥27の場合n \ ge log_2(1e8)\ ge 27nl o g21 e 8 データへの答え2 7がある0 00
のためのn≤N \ルlog_2(1E8)を2(1 E 8)ログnl o g21 e 8 ⌈log2i⌉\ lceil log_2i \ rceilを列挙できますL O G2I 、処理ブロック使用F(\ lfloor \ FRAC NI \ rfloor、K-1) - Fを(1⌊NI⌋、k)をf n個k1 、覚えるだけ+再帰的な解決策

詳細については、コードを参照してください。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<unordered_map>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int read()
{
    
    
	int res = 0,flag = 1;
	char ch = getchar();
	while(ch<'0' || ch>'9')
	{
    
    
		if(ch == '-') flag = -1;
		ch = getchar();
	}
	while(ch>='0' && ch<='9')
	{
    
    
		res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
		ch = getchar();
	}
	return res*flag;
}
const int maxn = 5e3+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
unordered_map<int,int>mp[27];
int f(int n,int k)
{
    
    
	if(k >= 27) return 0;
	if(mp[k].find(n) != mp[k].end())
		return mp[k][n];
	if(k == 0) return mp[k][n] = 1;
	else {
    
    
		int& tmp = mp[k][n];
		for(int i = 1;(1<<i) <= 2*n;i++)
		{
    
    
			int l = (1<<(i-1))+1,r = min(1<<i,n),rr;
			for(int j = l;j <= r;j = rr+1)
			{
    
    
				int pos = n/j;
				rr = min(r,n/pos);
				tmp = (tmp+1ll*i*(rr-j+1)%mod*f(pos,k-1))%mod;
			}
		}
		return tmp;
	}
}
int main()
{
    
    
	int n = read(),k = read();
	printf("%d\n",f(n,k));
	return 0;
}

おすすめ

転載: blog.csdn.net/qq_39641976/article/details/110733206