题意:给定一个序列,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=6[i1(i1-1)/2+i2(i2-1)/2+...+ik(ik-1)/2]+k                        

所以(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<intint> 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]数的拆分,数学推导的更多相关文章

  1. [国家集训队]整数的lqp拆分 数学推导 打表找规律

    题解: 考场上靠打表找规律切的题,不过严谨的数学推导才是本题精妙所在:求:$\sum\prod_{i=1}^{m}F_{a{i}}$ 设 $f(i)$ 为 $N=i$ 时的答案,$F_{i}$ 为斐波 ...

  2. 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 ...

  3. 关于不同进制数之间转换的数学推导【Written By KillerLegend】

    关于不同进制数之间转换的数学推导 涉及范围:正整数范围内二进制(Binary),八进制(Octonary),十进制(Decimal),十六进制(hexadecimal)之间的转换 数的进制有多种,比如 ...

  4. leetcode 343. Integer Break(dp或数学推导)

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...

  5. HDU 5073 Galaxy(Anshan 2014)(数学推导,贪婪)

    Galaxy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total S ...

  6. HDU-1719 Friend 数学推导

    Friend HDU - 1719 Friend number are defined recursively as follows. (1) numbers 1 and 2 are friend n ...

  7. 借One-Class-SVM回顾SMO在SVM中的数学推导--记录毕业论文5

    上篇记录了一些决策树算法,这篇是借OC-SVM填回SMO在SVM中的数学推导这个坑. 参考文献: http://research.microsoft.com/pubs/69644/tr-98-14.p ...

  8. UVA - 10014 - Simple calculations (经典的数学推导题!!)

    UVA - 10014 Simple calculations Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...

  9. 『sumdiv 数学推导 分治』

    sumdiv(POJ 1845) Description 给定两个自然数A和B,S为A^B的所有正整数约数和,编程输出S mod 9901的结果. Input Format 只有一行,两个用空格隔开的 ...

随机推荐

  1. 今天我们谈一下HTML标签中的<map>标签的用法和使用场景

    首先我们看下这个标签到底是干什么的! W3C的定义: 然后兼容性: 然后与之配套使用的另一个标签: <area/>规定其区域: 我们来看看<map>标签支不支持全局属性:=== ...

  2. bytectf2019 boring_code的知识学习&&无参数函数执行&&上海市大学生CTF_boring_code+

    参赛感悟 第三次还是第二次参加这种CTF大赛了,感悟和学习也是蛮多的,越发感觉跟大佬的差距明显,但是还是要努力啊,都大三了,也希望出点成绩.比赛中一道WEB都没做出来,唯一有点思路的只有EZCMS,通 ...

  3. Linux 常用到的命令

    1.按照文件所有属用户和名字查询 find -user mpsp -name \*.bin 2.根据string 字符串查找内容 more +/string test.txt 3.查找文件尾部 后20 ...

  4. Selenium常见报错问题(2)- 解决和分析StaleElementReferenceException异常

    如果你在跑selenium脚本时,需要某些异常不知道怎么解决时,可以看看这一系列的文章,看看有没有你需要的答案 https://www.cnblogs.com/poloyy/category/1749 ...

  5. shell脚本之awk(一)

     运维必备技能 概述: 1.awk是一种编程语言,用于linux/unix下对文本和数据进行扫描.处理数据来源:标准输入.文件.管道.  2.linux中常用的awk编译器版本有mawk,gawk.R ...

  6. 使用Spring Boot搭建你的第一个应用程序

    文章目录 依赖配置 main程序配置 MVC配置 安全配置 存储 Web 页面和Controller 异常处理 测试 结论 Spring Boot是Spring平台的约定式的应用框架,使用Spring ...

  7. 【linux题目】第一关

    详细的解答:https://github.com/Zoe233/Linux/blob/master/[题目]5.Linux了解程度测试题解析.ipynb 1. 创建一个目录/data 解答: mkdi ...

  8. 从零开始创建CocoaPods私有库

    为什么要创建CocoaPods私有库? 避免重复的造轮子 节约时间,方便管理自己的代码 精益求精 创建CocoaPods私有库 1.创建私有仓库工程 执行命令pod lib create SmartB ...

  9. dhcpd.conf(5) - Linux man page

    http://linux.die.net/man/5/dhcpd.conf Name dhcpd.conf - dhcpd configuration file Description   The d ...

  10. DefaultSingletonBeanRegistry源码解析

    DefaultSingletonBeanRegistry是SingletionBean注册器的默认实现. 来学习下DefaultSingletonBeanRegistry的源码: package or ...