CF 145C: Lucky Subsequence

来源:互联网 发布:纳网科技 中文域名 编辑:程序博客网 时间:2024/05/16 11:24

很简单的一道欧拉函数相关的题。。

但是我实在是对数论不熟,各种小错导致调了很久 T^T

题目链接:http://codeforces.com/contest/345/problem/C


通过这道题学习了欧拉函数的相关知识

逆元可以利用扩展欧几里德或欧拉函数求得(p为质数):

1).扩展欧几里德:b*x+p*y=1 有解,x就是所求

2).欧拉函数:b^(p-1)=1(mod p),故b*b^(p-2)=1(mod p),所以x=b^(p-2)
以上黄色部分引用自waitfor_的博客,非常感谢。

1、费马定理:a的p-1次方mod p余1。(其中p是素数,a是不能被p整除的正整数)
2、欧拉定理
2.1 欧拉函数
定义:欧拉函数phi(m):当m>1时,phi(m)表示比m小且与m互质的正整数个数
性质:(1)当m为素数时,phi(m)=m-1
         (2)当m=pq,且p和q是互异的素数,
                 则有:phi(m)=phi(p)*phi(p)=(p-1)(q-1) (这很好用)
         (3)m=p^e,且p为素数,e为正整数,则
                 phi(m)=p^e-p^(e-1)=(p^(e-1))*(p-1) 
定理:若m=p1^e1*p2^e2....pt^et则:
         phi(m)=m(1-1/p1)(1-1/p2)....(1-1/pt) (pi是素数)
2.2 欧拉定理
      a^phi(n)=1 mod n
      注:[1]n=p时候,有a^(p-1)=1 mod p,为费马定理
            [2]a^(phi(n)+1)=a mod n
            [3]若n=pq,p与q为相异素数,取大于0的m,n互质数,有
                 m^(phi(n)+1)=m mod n; m^((p-1)(q-1)+1)=m mod n
以上蓝色部分引自《一个数论里的概念 本原元》,同样感谢 > <

代码如下:
#include<cstdio>#include<iostream>#include<sstream>#include<cstdlib>#include<cstring>#include<string>#include<climits>#include<cmath>#include<algorithm>#include<queue>#include<vector>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define eps 1e-8using namespace std;const int MAXN=1100;const int MAXM=110000;int cot[10][1<<10];long long d[MAXN][MAXN];long long m[MAXM];const long long mod=1000000007;int f(int x) {    int tot=0,ret=0;    while(x) {        tot++;        int y=x%10;        x/=10;        if(y==4) {            ret=(ret<<1)^1;        } else if(y==7) {            ret<<=1;        } else return 0;    }    if(tot) {        cot[tot][ret]++;        if(cot[tot][ret]>1) {            return 1;        }    }    return 0;}long long pown(int x,int k) {    long long ans=1LL;    long long ret=x;    while(k) {        if(k&1) {            ans=(ans*ret)%mod;        }        ret=(ret*ret)%mod;        k>>=1;    }    return ans;}long long C(int n, int k) {    if(n<k) {        return 0LL;    }    long long ans=m[n];    ans=(ans*pown(m[n-k],mod-2))%mod;    ans=(ans*pown(m[k],mod-2))%mod;    return ans;}int main() {    int n,k;    m[0]=1;    for(int i=1; i<MAXM; i++) {        m[i]=(m[i-1]*i)%mod;    }    while(scanf("%d%d",&n,&k)==2) {        memset(cot,0,sizeof(cot));        int ret=0;        for(int i=0; i<n; i++) {            int x;            scanf("%d",&x);            ret+=f(x);        }        n-=ret;        if(n<k) {            puts("0");            continue;        }        long long ans=0LL;        int tot=0;        memset(d,0,sizeof(d));        d[0][0]=1LL;        for(int i=1; i<10; i++) {            for(int j=0; j<(1<<i); j++) {                if(cot[i][j]) {                    tot++;                    for(int num=tot; num; num--) {                        d[tot][num]=(d[tot-1][num]+d[tot-1][num-1]*cot[i][j])%mod;                    }                    d[tot][0]=d[tot-1][0];                }            }        }        for(int j=0; (j<=k)&&(j<=tot); j++) {            ans+=(d[tot][j]*C(n-tot,k-j))%mod;            ans%=mod;        }        printf("%I64d\n",ans);    }    return 0;}


原创粉丝点击