约数之和,约束个数

1.求所有约数

给定 n 个正整数 ai,对于每个整数 ai,请你按照从小到大的顺序输出它的所有约数。

 

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void get_prime(int x)
{
    vector<int> res;
    for(int i=1;i <= x / i;i++)
    {
        if(x % i == 0)
        {
            res.push_back(i);
            if(i != x/i) res.push_back(x/i);
        }
    }
    sort(res.begin(),res.end());
    for(auto re :res) cout<<re<<" ";
    cout<<endl;
}

int main()
{
    int n;
    cin>>n;
    while(n--)
    {
     
        int x;
        cin>>x;
        get_prime(x);
      
    }
    return 0;
}


2. 约数个数

公式:所有质因数个数的乘积。[(a1+1)*(a2+1)*(a3+1)*......*(ak+1)]

一个正整数N = p1^a1 * p2^a2 * ...... pk^ak 

p1,p2,p3,......,pk 是正整数的所有质因子

a1,a2,a3,......,ak 是对应的质因数存在的个数 (6 的质因子是 2 和3, 所以它有1个2,1个3,也就是2^1 * 3^1)

公式证明: 一个约数 X = p1^b1*p2^b2*......pk^bk (0<= bi <= ai)

(b1,b2,....,bk)  bi 只要在每一个【0,a】区间内任选一个值,都可以得到一个值,这个值就是N的约数。

6的约数 1, 2 ,3 ,6;

1=2^0 * 3^0

2= 2^1 * 3^0

3=2^0 * 3^1

6=2^1 * 3^1

每一个质因子有a+1([0,a] 闭区间)种选法,所以k个质因子有(a1+1)*(a2+1)*(a3+1)*......*(ak+1)种选法,得到的选法种数就是N的约数个数

#include<iostream>
#include<unordered_map>
#include<algorithm>
using namespace std;

typedef long long LL;
const int mod = 1e9 + 7;

int main()
{
    int n;
    cin>>n;
    
    unordered_map<int,int> prime;
    
    while(n--)
    {
        int a;
        cin>>a;
        
        for(int i=2; i <= a / i; i++)
        {
            while(a % i == 0)
            {
                a /= i;
                prime[i] ++;
            }
        }
        if(a > 1) prime[a] ++;
    }
    
    LL res = 1;
    for(auto p : prime) 
    {
        res = res * (p.second + 1) % mod;
        cout<<p.first<<" * "<<p.second<<endl;
    }
    cout<<res<<endl;
    return 0;
}

 

3.约数之和

公式:(p1^0 + p1^1 + ..... +p1^k)(p2^0 + p2^1 + ..... +p2^k)......(pk^0 + pk^1 + ..... +pk^k)

证明:把公式按乘法分配律展开 (从上述每一个括号中选一个数相乘)+()+() + .....+ ()

可以看出展开之后每个括号都是一个约数,共有约数个(上面求过的约数个数)括号。

#include<iostream>
#include<unordered_map>
#include<algorithm>
using namespace std;
const int mod = 1e9 + 7;
typedef long long LL;

int main()
{
    int n;
    cin>>n;
    
    unordered_map<int,int> prime;
    
    while(n--)
    {
        int x;
        cin>>x;
        for(int i=2;i<=x/i;i++)
        {
            while(x%i==0)
            {
                x/=i;
                prime[i] ++;
            }
           
        }
         if(x>1) prime[x] ++;
    }
    LL res = 1;
    for(auto p : prime)
    {
        int a = p.first  ,b = p.second;
        LL t = 1;
        while(b--) t = (t * a + 1) % mod;//求每一项p的乘积
        res = res * t % mod;
    }
    cout<<res<<endl;
    return 0;
}

p^0+p^1+p^2+.....+p^k =

while循环

第一次循环 t = p+1

第二次 t = (p+1) *p + 1

......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用sql语句完成任务:(一)存储函数的创建与使用 1.定义一个函数,计算两个数的最大公约数。 a) 输入两个整数。 b) 输出最大公约数。 c) 请用两种不同的方法实现gcd1()和gcd2()。 d) 调用c)中的两个函数,查找45和18的最大公约数。 e) 提示:可以通过辗转相除法找到两个数的最大公约数,流程图6-1如下。 图 6 1最大公约数流程图 2.课程的评分通常分为百分制和等级制。创建存储函数do_convert(),实现其转换,要: a) 输入指定百分制成绩。 b) 输出对应的等级制成绩。 c) 转换规则,如果>=90分则为优秀,80-90(包含80)为良好,70-80(包含70)为中等,60-70(包含60)为及格,否则为不及格。 d) 查询该函数是否创建成功。 e) 使用d)中的函数,查询A课程学生的等级成绩,查询输出如下。 输出如下: 学生学号 学生姓名 学生班级号 等级制成绩 (二)触发器的创建与使用 1.使用触发器实现单列取值的范围约束。要tbl_student学生表的生日字段要么为空,要么必须大于等于‘1900-01-01‘,小于今年。 a) 实现触发器birthday_check_trigger对表的更新约束。 b) 请找两个例子,验证触发器是否是实现了检查约束。 2.在进销存数据库创建触发器,对数据进行一致性约束。当销售表tbl_sell增加一条数据时,商品表的tbl_goods库存量减去对应的销量。当进货表tbl_receive增加一条数据时,商品表的库存量增加对应的进货数量。
05-30
对于第一部分,存储函数的创建与使用,我可以给出以下的 SQL 代码实现: 1. gcd1() 函数的创建: ``` CREATE FUNCTION gcd1(a INT, b INT) RETURNS INT BEGIN DECLARE r INT; WHILE b != 0 DO SET r = a % b; SET a = b; SET b = r; END WHILE; RETURN a; END; ``` 2. gcd2() 函数的创建: ``` CREATE FUNCTION gcd2(a INT, b INT) RETURNS INT BEGIN IF b = 0 THEN RETURN a; ELSE RETURN gcd2(b, a % b); END IF; END; ``` 3. 调用 gcd1() 和 gcd2() 函数: ``` SELECT gcd1(45, 18); SELECT gcd2(45, 18); ``` 4. do_convert() 函数的创建: ``` CREATE FUNCTION do_convert(score INT) RETURNS VARCHAR(10) BEGIN DECLARE grade VARCHAR(10); IF score >= 90 THEN SET grade = '优秀'; ELSEIF score >= 80 THEN SET grade = '良好'; ELSEIF score >= 70 THEN SET grade = '中等'; ELSEIF score >= 60 THEN SET grade = '及格'; ELSE SET grade = '不及格'; END IF; RETURN grade; END; ``` 5. 查询 do_convert() 函数是否创建成功: ``` SELECT ROUTINE_NAME, ROUTINE_DEFINITION FROM information_schema.ROUTINES WHERE ROUTINE_NAME = 'do_convert'; ``` 6. 使用 do_convert() 函数查询 A 课程学生的等级成绩: ``` SELECT student_id, student_name, class_id, do_convert(score) FROM score WHERE course_name = 'A'; ``` 对于第二部分,触发器的创建与使用,我可以给出以下的 SQL 代码实现: 1. 创建生日检查触发器: ``` CREATE TRIGGER birthday_check_trigger BEFORE INSERT ON tbl_student FOR EACH ROW BEGIN IF NEW.birthday < '1900-01-01' OR NEW.birthday > CURDATE() THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Birthday must be between 1900-01-01 and today.'; END IF; END; ``` 2. 验证触发器是否实现了检查约束,例如: ``` -- 例子1:插入生日为空的记录 INSERT INTO tbl_student (student_id, student_name, birthday, class_id) VALUES (1, 'Tom', NULL, 1); -- 例子2:插入生日不在范围内的记录 INSERT INTO tbl_student (student_id, student_name, birthday, class_id) VALUES (2, 'Jerry', '1899-12-31', 2); ``` 3. 创建销售和进货触发器: ``` -- 销售表 CREATE TRIGGER sell_trigger AFTER INSERT ON tbl_sell FOR EACH ROW BEGIN UPDATE tbl_goods SET stock = stock - NEW.quantity WHERE goods_id = NEW.goods_id; END; -- 进货表 CREATE TRIGGER receive_trigger AFTER INSERT ON tbl_receive FOR EACH ROW BEGIN UPDATE tbl_goods SET stock = stock + NEW.quantity WHERE goods_id = NEW.goods_id; END; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值