URAL1091. Tmutarakan Exams(容斥)

1091

容斥原理 

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 using namespace std;
 8 int p[110],g,f[55],q[55],o,vis[55],pa[55],n,kk;
 9 #define LL long long
10 void init()
11 {
12     int i,j;
13     for(i = 2; i < 50 ; i++)
14     if(!f[i])
15     for(j = i+i ; j < 50 ; j+=i)
16     f[j] = 1;
17     for(i = 2; i < 50 ; i++)
18     if(!f[i])
19     p[++g] = i;
20 }
21 LL find(int num,int k)
22 {
23     if(num<k) return 0;
24     int i,x=k;
25     LL s = 1;
26     for(i = 1; i <= k ; i++)
27     {
28         s*=num;
29         num--;
30         while(x>1&&s%x==0)
31         {
32             s/=x;
33             x--;
34         }
35     }
36     return s;
37 }
38 LL dfs(int k,int v,int a)
39 {
40     int i,j;
41     LL s=0;
42     if(a==o+1&&v==k)
43     {
44         for(i = 1; i <= n ; i++)
45         {
46             for(j = 1; j <= v ; j++)
47             if(i%pa[j]!=0)
48             break;
49             if(j==v+1)
50             s++;
51         }
52         s = find(s,kk);
53         return s;
54     }
55     if(a>o) return 0;
56     pa[v+1] = p[a];
57     s+=dfs(k,v+1,a+1);
58     s+=dfs(k,v,a+1);
59     return s;
60 }
61 int main()
62 {
63     int i,j;
64     init();
65     cin>>kk>>n;
66     LL s=0;
67     for(i = 1; i <= g ; i++)
68     {
69         int num = 0;
70         for(j = 2; j <= n ; j++)
71         if(j%p[i]==0)
72         num++;
73         if(num<kk) continue;
74         q[++o] = p[i];
75         s+=find(num,kk);
76     }
77     for(i = 2; i <= o ; i++)
78     {
79         memset(vis,0,sizeof(vis));
80         LL pp=dfs(i,0,1);
81         if(i%2==0)
82         s-=pp;
83         else
84         s+=pp;
85     }
86     if(s>=10000)
87     cout<<"10000"<<endl;
88     else
89     cout<<s<<endl;
90     return 0;
91 }
View Code

 

posted @ 2013-11-10 14:06  _雨  阅读(186)  评论(0编辑  收藏  举报