容斥原理 + 大数模板(跳蚤 POJ

来源:互联网 发布:淘宝头像 编辑:程序博客网 时间:2024/05/22 12:38

欢迎大家来刷我的专题:https://vjudge.net/contest/177165#problem/I
这是一道数范围很大的题,据说数据很水.

首先题目的意识也就是 一个方程有解,系数都是<=m,最后一个系数为m,这个等于1的方程一定有解的话,也就是说这n+1个系数的gcd=1,互质,那么解决问题的思路就有莫比乌斯反演,欧拉函数,容斥原理等等,不过这道题的话,前两个不是很好想.
这里简要说一下容斥原理的思路.
容斥原理: 一共有mn种 , 然后只要删掉 gcd>1的情况就行了, 因为已经有了M这个系数,我们就先对他做一个处理,提取他的质因数,如果gcd/2==0,那么也就是 (m/2)n , 考虑容斥,

答案显然就是  

mn(mp1)n(mp2)+...+(mp1p2)+...

#include<cstdio>#include<iostream>#include<bitset>#include<cstring>#define ll long longconst int maxn = 1e3;using namespace std;int tot = 0;int n,m;struct BigInt{    const static int mod = 10;    int a[maxn], len;    BigInt(){        memset(a, 0, sizeof a);        len = 1;    }    BigInt(ll v){        memset(a, 0, sizeof a);        len = 0;        do{            a[len++] = v%mod;            v/=mod;        }while(v);    }    BigInt operator +(const BigInt &b)const{        BigInt res;        res.len = max(len, b.len);        for(int i = 0; i <= res.len; i++){            res.a[i] = 0;        }        for(int i = 0; i < res.len; i++){            res.a[i] += ((i < len)?a[i]:0) + ((i < b.len)?b.a[i]:0);            res.a[i+1] += res.a[i]/mod;            res.a[i] %= mod;        }        if(res.a[res.len] > 0) res.len++;        return res;    }    //保证a>=b    BigInt operator -(const BigInt &b)const{        BigInt res;        res.len = len;        for(int i = 0; i <= res.len; i++){            res.a[i] = 0;        }        for(int i = 0; i < res.len; i++){            res.a[i] += (a[i]-b.a[i]);            if(res.a[i]<0){                res.a[i]+=10;                res.a[i+1]--;            }        }        while(res.a[res.len-1]==0 && res.len > 1)res.len--;        return res;    }    BigInt operator *(const BigInt &b)const{        BigInt res;        for(int i = 0; i < len; i++){            int up = 0;            for(int j = 0; j < b.len; j++){                int temp = a[i]*b.a[j] + res.a[i+j] + up;                res.a[i+j] = temp%mod;                up = temp/mod;            }            if(up != 0)                res.a[i + b.len] = up;        }        res.len = len + b.len;        while(res.a[res.len - 1] == 0 && res.len > 1)res.len--;        return res;    }    void output(){        for(int i = len-1; i >= 0; i--)            printf("%d",a[i]);    }    void init(){        memset(a, 0, sizeof a);        len = 1;    }};BigInt power(BigInt a, int b){    BigInt ans = BigInt(1);    while(b){        if(b&1) ans = ans*a;        a = a*a;        b >>= 1;    }    return ans;}int p[maxn];int main(){    while(~scanf("%d%d",&n,&m)){        int tot = 0;        int mm = m;        for(int i = 2; i <= m/i; i++){            if(m%i==0){                p[tot++] = i;            }            while(m%i==0){                m/=i;            }        }        if(m>1){            p[tot++] = m;        }        BigInt ans = power(mm, n);        ll tmp = 1;        int c = 0;        for(int i = 1; i < 1<<tot; i++){            c = 0; tmp = mm;            for(int j = 0; j < tot; j++)            if(i & (1 << j)){                c++;                tmp/=p[j];            }            BigInt it = BigInt(tmp);            if(c&1) ans = ans - power(it, n);            else ans = ans + power(it, n);            //ans.output();            //puts("");        }        ans.output();        puts("");    }    return 0;}
原创粉丝点击