传送门:http://codeforces.com/contest/822/problem/D
题意:求${t^0}f(l) + {t^1}f(l + 1) + ... + {t^{r - l}}f(r)$ f(x)代表每次把x个人分成人数相等的若干个组进行比赛,每组有一个胜利的情况下,最后淘汰到只剩一个人需要最少进行比赛的次数 例如f(2)=1。
很明显的看出是dp问题 假设f(100)被分为50个2人组答案一定为f(50)+1*50 很容易能观察到每队分配越少人的情况下答案越优。
证明:简单证明的话可以假设每次都分为d个人一组,人数为n 大约需要的总次数大约为logd(n)*d求导后为单调增函数,但是这样证明不是很准确。官方证明是假设d为合数,有d=a*b,可以推导出,所以d为素数时最优,代码如下。
ps:此类可以暴力的题目对拍查错效率很高!
1 #define _CRT_SECURE_NO_DEPRECATE 2 #pragma comment(linker, "/STACK:102400000,102400000") 3 #include<iostream> 4 #include<cstdio> 5 #include<fstream> 6 #include<iomanip> 7 #include<algorithm> 8 #include<cmath> 9 #include<deque> 10 #include<vector> 11 #include<assert.h> 12 #include<bitset> 13 #include<queue> 14 #include<string> 15 #include<cstring> 16 #include<map> 17 #include<stack> 18 #include<set> 19 #include<functional> 20 #define pii pair<int, int> 21 #define mod 1000000007 22 #define mp make_pair 23 #define pi acos(-1) 24 #define eps 0.00000001 25 #define mst(a,i) memset(a,i,sizeof(a)) 26 #define all(n) n.begin(),n.end() 27 #define lson(x) ((x<<1)) 28 #define rson(x) ((x<<1)|1) 29 #define inf 0x3f3f3f3f 30 typedef long long ll; 31 typedef unsigned long long ull; 32 using namespace std; 33 34 const int maxn = 5e6 + 5; 35 ll dp[maxn]; 36 37 bool visit[maxn]; 38 ll prime[maxn]; 39 ll sve[maxn]; 40 void getprime() 41 { 42 int n = 5000000; 43 memset(visit, false, sizeof(visit)); 44 int num = 0; 45 for (ll i = 2; i <= n; ++i) 46 { 47 if (!visit[i]) { prime[++num] = i; sve[i] = i; } 48 for (int j = 1; j <= num && i * prime[j] <= n; j++) 49 { 50 int temp = i*prime[j]; 51 visit[temp] = true; 52 if (!sve[temp])sve[temp] = min(i, prime[j]); 53 if (i % prime[j] == 0) break; 54 } 55 } 56 } 57 int main() 58 { 59 ios::sync_with_stdio(false); 60 cin.tie(0); cout.tie(0); 61 int i, j, k, m, n, l, r; 62 ll t; 63 cin >> t >> l >> r; 64 getprime(); 65 for (ll i = 2; i <= r; ++i) 66 dp[i] = ((sve[i] * (sve[i] - 1LL)) / 2LL * (i / sve[i]) + dp[i / sve[i]]) % mod; 67 ll sum = 0; 68 ll temp = 1; 69 for (int i = l; i <= r; ++i) 70 { 71 sum = (sum + temp*dp[i]) % mod; 72 temp *= t; 73 temp %= mod; 74 } 75 cout<<sum; 76 return 0; 77 }