[hdu5312]数的拆分,数学推导
题意:给定一个序列,a[n]=3n(n-1)+1,n>=1,求给定的m(m<=1e9)最少可以用几个a里面的数表示(可以重复)
思路:对答案分类
(1)假定答案为1,则m必定是a中的某一个数,直接查找即可,复杂度O(logn)
(2)假定答案为2,则m必定可以拆分成两个a中的数之和,用两指针分别从头和尾向中间扫,判断是否可以构成m,复杂度O(n)
(3)假定答案大于等于3,设答案为k,即k>=3,则必有m=a[i1]+a[i2]+...+a[ik],由于a[i]=3i(i-1)+1=6[i(i-1)/2]+1,所以有:
所以(m-k)%6==0恒成立,也就是说如果得出了答案k,那么答案一定满足(m-k)%6==0,这是必要性;当k>=3时,令b=(m-k)/6,因为任意一个自然数最多只需要3个三角形数即可表示,所以b=i1(i1-1)/2+i2(i2-1)/2+...+ik(ik-1)/2恒有解,这是充分性。故答案k需满足k>=3且(m-k)%6==0,由于是求最小个数,k从3枚举到第一次满足(m-k)%6==0即可得到答案。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
#include <iostream>#include <cstdio>#include <cmath>#include <cstdlib>#include <cstring>#include <vector>#include <ctime>#include <deque>#include <queue>#include <algorithm>using namespace std;#define pb push_back#define mp make_pair#define X first#define Y second#define all(a) (a).begin(), (a).end()void readInt(){}void RI(int&X){scanf("%d",&X);}template<typename...R>void RI(int&f,R&...r){RI(f);RI(r...);}void RIA(int*p,int*q){int d=p<q?1:-1;while(p!=q){scanf("%d",p);p+=d;}}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;}typedef pair<int, int> pii;typedef long long ll;typedef unsigned long long ull;template<typename T>bool umax(T &a, const T &b) { return a >= b? false : (a = b, true);}/* -------------------------------------------- */vector<int> table;void init() { for (int i = 1; ; i ++) { ll buf = 3ll * i * (i - 1) + 1; if (buf > 1e9 + 7) break; table.pb((int)buf); }}bool chk(int x) { int l = 0, r = upper_bound(all(table), x - table[0]) - table.begin() - 1; while (l < r && table[l] + table[r] != x) { l ++; while (l < r && table[l] + table[r] > x) r --; } return table[l] + table[r] == x;}int main() {#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin);#endif // ONLINE_JUDGE int T; cin >> T; init(); while (T --) { int x; RI(x); if (find(all(table), x) != table.end()) { puts("1"); continue; } if (chk(x)) { puts("2"); continue; } for (int k = 3; ; k ++) { if ((x - k) % 6 == 0) { printf("%d\n", k); break; } } } return 0;} |
[hdu5312]数的拆分,数学推导的更多相关文章
- [国家集训队]整数的lqp拆分 数学推导 打表找规律
题解: 考场上靠打表找规律切的题,不过严谨的数学推导才是本题精妙所在:求:$\sum\prod_{i=1}^{m}F_{a{i}}$ 设 $f(i)$ 为 $N=i$ 时的答案,$F_{i}$ 为斐波 ...
- luogu 4844 LJJ爱数数 (莫比乌斯反演+数学推导)
题目大意:求满足gcd(a,b,c)==1,1/a+1/b=1/c,a,b,c<=n的{a,b,c}有序三元组个数 因为题目里有LJJ我才做的这道题 出题人官方题解https://www.cnb ...
- 关于不同进制数之间转换的数学推导【Written By KillerLegend】
关于不同进制数之间转换的数学推导 涉及范围:正整数范围内二进制(Binary),八进制(Octonary),十进制(Decimal),十六进制(hexadecimal)之间的转换 数的进制有多种,比如 ...
- leetcode 343. Integer Break(dp或数学推导)
Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...
- HDU 5073 Galaxy(Anshan 2014)(数学推导,贪婪)
Galaxy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total S ...
- HDU-1719 Friend 数学推导
Friend HDU - 1719 Friend number are defined recursively as follows. (1) numbers 1 and 2 are friend n ...
- 借One-Class-SVM回顾SMO在SVM中的数学推导--记录毕业论文5
上篇记录了一些决策树算法,这篇是借OC-SVM填回SMO在SVM中的数学推导这个坑. 参考文献: http://research.microsoft.com/pubs/69644/tr-98-14.p ...
- UVA - 10014 - Simple calculations (经典的数学推导题!!)
UVA - 10014 Simple calculations Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...
- 『sumdiv 数学推导 分治』
sumdiv(POJ 1845) Description 给定两个自然数A和B,S为A^B的所有正整数约数和,编程输出S mod 9901的结果. Input Format 只有一行,两个用空格隔开的 ...
随机推荐
- redis: Zset有序集合类型(七)
存值:zadd myset 1 one 取值:zrange myset 0 -1 127.0.0.1:6379> zadd myset 1 one #存值 分值为1 (integer) 1 12 ...
- Java中集合的嵌套
集合的嵌套遍历 获取10个1-20之间的随机数,要求不能重复 键盘录入多个数据,以0结束,要求在控制台输出这多个数据的最大值. public static void main(String[] arg ...
- 树莓派3b在rt-thread上移植LittlevGL
树莓派3b在rt-thread上移植LittlevGL 目录 树莓派3b在rt-thread上移植LittlevGL 1.本文概述 2.资源准备 3.上手体验 4.rt-thread与lvgl进行无缝 ...
- SpringBoot项目集成Redis
一.在pom文件中添加依赖 <!-- 集成redis --> <dependency> <groupId>org.springframework.boot</ ...
- apt 安装 版本
1. 通过apt-get安装指定版本软件 apt-get install package=version 2. 查询指定软件有多少个版本 2.1 通过网站搜索https://packages.ubun ...
- Ubuntu 安装 Qt, 安装辅助软件
sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev sudo apt-get install gcc g++ sudo apt-get inst ...
- Golang Map实现(四) map 的赋值和扩容
title: Golang Map 实现 (四) date: 2020-04-28 18:20:30 tags: golang map 操作,是map 实现中较复杂的逻辑.因为当赋值时,为了减少has ...
- 播放声音 (c++) (windows)
自己看自己看自己看自己看自己看自己看 在<windows.h>中 一:BOOL WINAPI MessageBeep (_in UINT uType ); 播放一个波形文件 (也就是wac ...
- Tomcat实现Session复制
Tomcat实现Session复制 需要三台虚拟机一台Nginx两台Tomcat 关闭相关的安全机制 systemctl stop firewalldiptables -Fsetenforce 0 首 ...
- 使用sys模块写一个软件安装进度条
import sys,time for i in range(50): sys.stdout.write('#') sys.stdout.flush() #强制刷新将内存中的文件写一条,输出一条. t ...