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

 

你可能感兴趣的:(tar)