newcoder 周赛143 C 费马小定理和质因数分解相关优化

zhe ta ma shi C ti gai you de yang zi ma

费马小定理

image
image

代码及其注释

https://ac.nowcoder.com/acm/contest/134529/C

#include<bits/stdc++.h>
using namespace std;
//"O campeão tem nome, e se chama Charles Oliveira!"
#define int long long
#define endl '\n'
#define ep emplace
#define pob 
#define ll long long
#define pb push_back
#define pof pop_front
#define pob pop_back
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define mod 998244353
#define MOD 1000000007
const int N=200005;

using ld = long double;
using ui = unsigned;
using ull = unsigned long long;
using i128 = __int128;
/**
 * 思路大概就是给一个X和Y,要求得是这两个数字相乘得结果得质因数A A^A的和
 * 比如假设X*Y=20的结果就是1*1+2*2+4*4+......20*20
 * 如果硬算的话,因为X和Y的数据范围都是1e9+7,把两个乘起来用根号来求质因数还是会T
 * 
 * 可以知道假设 x*y=A1^x1+A2^x2+A3^x3.......,那么x*y的所有可以约的数就是A1^y+A2^y1+A3^y3......
 * 这里的y可以是0次,一次,2次.....fac[A1]
 * 这里的y1可以是0次,一次,2次......fac[A2]
 * 
 * 如果都是0次,那么就是1了,一个也不选那么就是1,1也正好是范围内的数字
 */
int fastpower(int base,int exp){
    int res=1;
    base%=MOD;
    while(exp){
        if(exp&1)res=(res*base)%MOD;
        base=(base*base)%MOD;
        exp>>=1;
    }
    return res;
}
map<int,int>fac;
void factors(int x){
    for(int i=2;i*i<=x;i++){
        while(x%i==0)
        {
        fac[i]++;
        x/=i;
        }
    }
    if(x>1)fac[x]++;//注意这里没有包含1!
    //因为下面dfs就是从1开始的,只要一路dfs下去一个都不选,就是ans+=1;
}
vector<pair<int,int>>v;
int total_ans=0;
void dfs(int idx,int d){
    if(idx==v.size()){
        if(d%MOD==0)return ;
        //费马小定理
        else total_ans=(total_ans+fastpower(d%MOD,d%(MOD-1)))%MOD;
        return ;
    }
    int cnt=v[idx].second;
    int poww=1;
    //这个for loop从0开始就是考虑到了可以一个都不选,也就是选一个到选cnt个加上1个什么都不选
    for(int i=0;i<=cnt;i++){
        dfs(idx+1,d*poww);
        if(i<cnt)poww*=v[idx].first;
        //这里不可以写成poww=(poww*v[idx].first)%MOD;
        //原因就是这样传入就变成了fastpower(d%mod%mod,d%mod%(mod-1))!=fastpower(d%mod,d%(mod-1));
    }
}
void solve(){
    int x,y;
    cin>>x>>y;
    factors(x);
    factors(y);
    for(auto &[x,y]:fac){
        v.push_back({x,y});
    }
    dfs(0,1);
    cout<<total_ans<<endl;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t=1;
    //cin>>t;
    while(t--)solve();
}
posted @ 2026-05-12 21:00  Time_q  阅读(14)  评论(0)    收藏  举报