码迷,mamicode.com
首页 > 其他好文 > 详细

容斥原理——poj1091

时间:2019-05-14 20:48:56      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:分解质因子   位置   return   不同   ==   +=   方案   pow   dfs   

将m质因子分解,然后枚举选取的质因子个数i进行容斥,每种情况进行一次dfs即可

dfs结束标记:当质因子个数达到i时退出递归,同时累加该解对应的方案数

/*
给定n,m
共有n个数的数组a,不超过m
m^n减掉 gcd(a)>1的情况
先把m质因数分解
然后枚举不同的质因子个数即可 
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define ll long long 

ll n,m,p[1005],mm,ans,sum;

ll Pow(ll a,ll b){
    ll res=1;
    while(b){
        if(b%2)res=res*a;
        b>>=1;a=a*a;
    }
    return res;
}
void divide(){
    mm=0;ll tmp=m;
    for(int i=2;i*i<=m;i++)
        if(tmp%i==0){
            p[++mm]=i;
            while(tmp%i==0)tmp/=i;
        }
    if(tmp>1)p[++mm]=tmp;
}

int a[30];//临时数组用来存用到的质因子 
void get_sum(int pos,int cnt,int num){
    if(cnt>num){//搜出了一组解 
        ll tmp=m;
        for(int i=1;i<cnt;i++)tmp/=a[i];
        sum+=Pow(tmp,n);
        return;
    }
    for(int i=pos;i<=mm;i++)//枚举下一个位置 
        a[cnt]=p[i],get_sum(i+1,cnt+1,num);
}

int main(){
    while(cin>>n>>m){
        ans=Pow(m,n);
        divide();//分解质因子m 
        for(int i=1;i<=mm;i++){
            sum=0;
            get_sum(1,1,i);
            if(i&1) ans-=sum;//关于质因子个数的容斥 
            else ans+=sum;
        }
        cout<<ans<<endl;
    }
}
 

 

容斥原理——poj1091

标签:分解质因子   位置   return   不同   ==   +=   方案   pow   dfs   

原文地址:https://www.cnblogs.com/zsben991126/p/10864376.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!