[hdu5439 Aggregated Counting]公式化简,预处理
题意:按下列规则生成一组序列,令f(n)为n这个数在序列中出现的最后一个位置,求f(f(n))的值。
1. First, write down 1, 2 on a paper.
2. The 2nd number is 2, write down 2 2’s (including the one originally on the paper). The paper thus has 1, 2, 2 written on it.
3. The 3rd number is 2, write down 2 3’s. 1, 2, 2, 3, 3 is now shown on the paper.
4. The 4th number is 3, write down 3 4’s. 1, 2, 2, 3, 3, 4, 4, 4 is now shown on the paper.
5. The procedure continues indefinitely as you can imagine. 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, . . . .
思路:令原序列为a,根据定义和序列的生成规则可以推出:
- f(n)等于a的前n项和
- f(n)是n这个数在a中出现的最后一个位置
f(f(n))的含义为:a的前m项和,m为n在a中最后出现的位置。所以f(f(n))的计算式可以写成:
f(f(n))=1 + (2+3)*2 + (4+5)*3 + (6+7+8)*4 + ... + (...+n)*t
t是远小于n的,大概为几十万的样子,剩下的就不多说了。。。
#pragma comment(linker, "/STACK:10240000") #include <bits/stdc++.h> using namespace std; #define X first #define Y second #define pb push_back #define mp make_pair #define all(a) (a).begin(), (a).end() #define fillchar(a, x) memset(a, x, sizeof(a)) typedef long long ll; typedef pair<int, int> pii; namespace Debug { void print(){cout<<endl;}template<typename T> void print(const T t){cout<<t<<endl;}template<typename F,typename...R> void print(const F f,const R...r){cout<<f<<" ";print(r...);}template<typename T> void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;} } template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);} template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);} /* -------------------------------------------------------------------------------- */ const int maxn = 1e9 + 7; const int mod = maxn; int seq[600000] = {0, 1, 2, 2}; ll sum[600000] = {0, 1, 3, 5}, ans[600000]; int total = 3; void init() { for (int i = 3; ; i ++) { for (int j = 0; j < seq[i]; j ++) { seq[++ total] = i; sum[total] = sum[total - 1] + seq[total]; } if (sum[total] > maxn) break; } ans[1] = 1; for (int i = 2; i < total; i ++) { ans[i] = (ans[i - 1] + (sum[i] + sum[i] - seq[i] + 1) * seq[i] / 2 % mod * i) % mod; } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // ONLINE_JUDGE int T, n; init(); cin >> T; while (T --) { cin >> n; int p = upper_bound(sum + 1, sum + total, n) - sum - 1; cout << (ans[p] + (sum[p] + 1 + n) * (n - sum[p]) / 2 % mod * (p + 1)) % mod << endl; } }