zoukankan      html  css  js  c++  java
  • 约数之和(acwing)

    题目链接

    题目

    img

    思路

    最开始的思路:

    把A拆成 (a_1 imes a_2) , 那么(A^B) 就变成了(a_1^B imes a_2^B) ,那么(a1)(a2)能提供的因子(约数)有:

    (a_1^0) , (a_1^1) , (a_1^2) (cdots a_1^B)

    (a_2^0) , (a_2^1) , (a_2^2)(cdots a_2^B)

    还有:

    (a_1^0 imes a_2^0) ,(a1^0 imes a2^1),(a_1^0 imes a_2^2)(cdots)

    (a_1^1 imes a_2^0),(a_1^1 imes a_2^1),(a_1^1 imes a_2^2)(cdots)

    (cdots)(cdots)(cdots)

    用一个map记录是否出现过这个因子,然后计算约数和

    (A , B)范围在(5^7)所以必然T了

    后来的思路:

    一个数的因子,要么是质数,要么是数个质数的乘积

    那么我把一个数拆成一堆的质因子相乘,这个数的所有约数都是由这些质因子转化来的

    对任意数(x) , 根据唯一分解定理有:

    (x = p_1 ^{x_1} imes p_2 ^{x_2} imes p_3 ^{x_3}ldots imes p_m ^{x_m})

    也就是说(x)的某个因子(v = p_1 ^{i_1} imes p_2 ^{i_2} imes p_3 ^{i_3}ldots imes p_m ^{i_m})

    然后问让你求所有因子的和也就是求:

    $sum = (p_1 ^0 + p_1 ^{1} + p_1 ^{2}ldots+ p_1 ^{x_1}) imes (p_2 ^0 + p_2 ^{1} + p_2 ^{2}ldots+ p_1 ^{x_2}) imesldots imes(p_m ^0 + p_m ^{1} + p_m ^{2}ldots+ p_m ^{x_m}) $

    为什么是这个公式,举个栗子:

    (A = 30 , B = 2)

    (A = 2^1 imes 3^1 imes 5^1)

    (A^B = (2^1 imes 3^1 imes 5^1)^B = 2^B imes 3^B imes 5^B = 2^2 imes 3^2 imes 5^2)

    对于质因子(2)来说:

    (2^0)对答案的贡献是:(2^0 imes (3^0 imes 5^0 + 3^0 imes 5^1 + 3^0 imes 5^2 + 3^1 imes 5^0 +ldots +3^2 imes 5^2) = 2^0 imes(3^0 + 3^1 + 3^2) imes (5^0 + 5^1 + 5^2))

    同理:(2^1)对答案的贡献是$ 2^1 imes(3^0 + 3^1 + 3^2) imes (5^0 + 5^1 + 5^2)$

    等等等等(...)

    #include<bits/stdc++.h>
    #define int long long 
    #define ll long long
    #define pb(a) push_back(a)
    #define fi first
    #define se second
    #define mp(a , b) make_pair(a , b)
    using namespace std;
    ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}//xμ?n′?·?mod
    const int mod = 9901; 
    vector< pair<int , int> > vec;
    signed main()
    {
    	int a , b;
    	cin >> a >> b;
    	if(a == 0)return cout << "0
    " , 0;
    	else if(b == 0) return cout << "1
    " , 0;
    	for(int i = 2 ; i * i <= a ; i ++){
    		if(a % i == 0){
    			int cnt = 0;
    			while(a % i == 0) a /= i , cnt ++; 
    			vec.pb(mp(i , cnt));
    		}
    	}
    	if(a != 1)	vec.pb(mp(a , 1));
    	int ans = 1;
    	for(int i = 0 ; i < vec.size() ; i ++){
    		int now = (pow_mod(vec[i].fi , (b * vec[i].se) + 1 % mod , mod) - 1) * pow_mod(vec[i].fi - 1 , mod - 2 , mod);
    		if(vec[i].fi % mod == 1)  now = vec[i].se * (b * vec[i].fi) % mod + 1 % mod;
    		ans *= now % mod , ans %= mod;
    	}
    	cout << (ans % mod + mod) % mod << '
    ';
    	return 0;
    }
    

  • 相关阅读:
    页断裂(partial write)与doublewrite技术
    mysql大小写敏感与校对规则
    mysql自增列导致主键重复问题分析。。。
    一次进程hang住问题分析。。。
    教你手工mysql拆库
    mysql online ddl
    Yii2的深入学习--入口文件
    构建自己的PHP框架--抽象Controller的基类
    构建自己的PHP框架--抽象框架的内容
    构建自己的PHP框架--搭建基本结构
  • 原文地址:https://www.cnblogs.com/GoodVv/p/13892356.html
Copyright © 2011-2022 走看看