hdu 5439(找规律)
2015-09-21 17:27
375 查看
The sequence is generated by the following scheme.
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, . . . .
所求答案为前n项i*f[i]的和,f[i] 有i个,所以1e9大概需要算到5e5就行(参考别人的思路),
upper_bound查找(好像是二分查找),自己按思路写的最开始用的for查找,发现比别人慢很多,然后才注意到这个函数,以前虽然知道,但并没怎么用过- -。
预处理:sum存到i时数的个数,g保存到i最后一个时的i*f[ i ]值。因为n找到后不一定是i的最后一个,再填上多出部分即可
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, . . . .
所求答案为前n项i*f[i]的和,f[i] 有i个,所以1e9大概需要算到5e5就行(参考别人的思路),
upper_bound查找(好像是二分查找),自己按思路写的最开始用的for查找,发现比别人慢很多,然后才注意到这个函数,以前虽然知道,但并没怎么用过- -。
预处理:sum存到i时数的个数,g保存到i最后一个时的i*f[ i ]值。因为n找到后不一定是i的最后一个,再填上多出部分即可
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<string> #include<map> #include<set> #include<vector> #include<queue> #include<stack> #include<functional> using namespace std; typedef long long ll; const int mod=1e9+7; const int maxn=5e5; int a[maxn]; ll sum[maxn]; int g[maxn]; int su(int a,int b) { int ans =(ll)(a+b)*(b-a+1)/2%mod; return ans; } int main() { a[1] = sum[1] = g[1] = 1; sum[2] = 3; g[2] = 11; a[2] = a[3] = 2; int cnt = 3; for(int i = 3; i < maxn; i++) { for(int j = 0; j < a[i]; j++) { if(cnt == maxn) break; a[++cnt] = i; } sum[i] = (sum[i-1] + a[i]); g[i] = (g[i-1]+ (ll)i*su(sum[i-1]+1,sum[i])) % mod; } int T,n,i; scanf("%d",&T); while(T--) { scanf("%d",&n); int tmp = n; int cur; for(i = 1; i < maxn; i++) { if(sum[i]>n){ cur = i-1; break; } } ll ans = g[cur] + (ll)(cur+1)*su(sum[cur]+1,tmp)%mod; printf("%d\n",ans%mod); } return 0; }
相关文章推荐
- 第4周实践项目1-- 建立单链表
- C语言实现“乘法口诀表”
- hdu 5439(找规律)
- VEX Control(控制)
- Effective C++——条款49(第8章)
- 将函数声明为Static的作用
- 手机购物车添加动画
- iOS 重命名项目的完整方法
- ThreadPoolExecutor使用和思考-线程池大小设置与BlockingQueue的三种实现区别
- 第四周项目1-建立单链表
- /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found
- NSFileManager
- Opencv3.0+opencv_contrib_lib +VS2013(编译)+CMake-gui(最近的版本都可以)
- 小米路由器青春版中继模式后登陆
- jquery查找子元素
- js图片上传预览功能
- iostream与iostream.h乱弹琴
- C#数据缓存介绍及Caching通用帮助类整理
- mysql 查询条件中文问题
- 指定方向或者位置移动