前言
容斥原理:看集合,一般为大集合减去小集合,即集合的总数-不符合的集合
提示:以下是本篇文章正文内容,下面案例可供参考
一、容斥原理
能被整除的数:
给定一个整数 n
和 m
个不同的质数 p1,p2,…,pm
。
请你求出 1∼n
中能被 p1,p2,…,pm
中的至少一个数整除的整数有多少个。
输入格式
第一行包含整数 n
和 m
。
第二行包含 m
个质数。
输出格式
输出一个整数,表示满足条件的整数的个数。
数据范围
1≤m≤16
,
1≤n,pi≤109
输入样例:
10 2
2 3
输出样例:
7
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 20;
typedef long long LL ;
int p[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<m;i++) cin>>p[i];
int res=0;
for(int i=1;i<1<<m;i++)//i表示二进制左移m位,如00001变为10000
{
int t=1,s=0;
for(int j=0;j<m;j++)
if(i>>j&1)//如果j位是1的话
{
if((LL)t*p[j]>n)//则n/t下取整等于0
{
t=-1;
break;
}
t*=p[j];
s++;//表示当前有几个1(有几个集合)
}
if(t!=-1)
{
if(s%2) res+=n/t;//是偶数则加上
else res-=n/t;//是奇数则减去
//这是根据容斥原理的公式得来的,(-1)^(n-1)
}
}
cout<<res<<endl;
return 0;
}
A - 越狱
监狱有
�
n 个房间,每个房间关押一个犯人,有
�
m 种宗教,每个犯人会信仰其中一种。如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱。
答案对
100
,
003
100,003 取模。
Input
输入只有一行两个整数,分别代表宗教数
�
m 和房间数
�
n。
Output
输出一行一个整数代表答案。
Sample 1
Inputcopy Outputcopy
2 3
6
Hint
样例输入输出 1 解释
状态编号 1 号房间 2 号房间 3 号房间
1 信仰 1 信仰 1 信仰 1
2 信仰 1 信仰 1 信仰 2
3 信仰 1 信仰 2 信仰 2
4 信仰 2 信仰 1 信仰 1
5 信仰 2 信仰 2 信仰 2
6 信仰 2 信仰 2 信仰 1
数据规模与约定
对于
100
%
100% 的数据,保证
1
≤
�
≤
1
0
8
1≤m≤10
8
,
1
≤
�
≤
1
0
12
1≤n≤10
12
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod=100003;
ll fast(ll n,ll m)
{
ll res=1;
while(m)
{
if(m&1) res=res*n%mod;
n=n*n%mod;
m>>=1;
}
return res;
}
int main()
{
ll n,m;
cin>>m>>n;
cout << (((fast(m, n) - m*fast(m-1, n-1))%mod + mod)%mod);
return 0;
}
B - 炼金术(Alchemy
铃是一个爱玩游戏的女孩子。
她在游戏中想要炼制一种稀有合金 —— 这需要
�
n 种金属来合成。
她准备好矿石后建造了
�
k 个不同的熔炉,当熔炉启动时,会随机炼出这
�
n 种金属中的一些(也可能什么都没有)。
如果把每个熔炉炼出的金属收集起来,有了全部
�
n 种金属,就能造出合金了。澪对此很好奇,对铃说:「我考考你,有多少种情况可以炼出合金呢?」这个简单的问题铃很快就会做了,你能求出结果吗?
答案可能很大,请对
998244353
998244353 取模(即除以
998244353
998244353 的余数)后输出。
Input
输入一行两个正整数
�
,
�
n,k。
Output
输出一行一个整数,表示答案。
Sample 1
Inputcopy Outputcopy
2 2
9
Sample 2
Inputcopy Outputcopy
4 5
923521
Sample 3
Inputcopy Outputcopy
233 123
81633405
Hint
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod=998244353;
int ksm(ll a, ll b){
ll ans = 1;
while(b){
if(b & 1)
ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans;
}
int main()
{
ll n, k, ans = 0;
cin >> n >> k;
cout << ksm((ksm(2, k)-1+mod)%mod, n) << endl;
return 0;
return 0;
}
总结
提示:这里对文章进行总结:
容斥原理要注意正负号,关键要先求出通式方程