容斥原理
数学2(容斥原理)
P3197 [HNOI2008] 越狱
发生越狱的状态数=总状态数-不越狱的状态数, 很显然总状态数为 , 而不越狱的状态数应该是同样宗教互不相邻, 第一个房间有 种,其他房间都是 种, 所以状态数应该是 。 答案: 代码:
#include
using namespace std;
#define int long long
const int mod=100003;
int m,n;
int mi(int x,int y){
int ans=1;
while(y){
if(y%2) ans*=x,ans%=mod;
y/=2,x=x*x%mod;
}
return ans;
}
signed main(){
cin>>m>>n;
cout
`#include
using namespace std;
#define int long long
const int mod=100003;
int m,n;
int mi(int x,int y){
int ans=1;
while(y){
if(y%2) ans*=x,ans%=mod;
y/=2,x=x*x%mod;
}
return ans;
}
signed main(){
cin>>m>>n;
coutmi(m,n)-m*mi(m-1,n-1)%mod+mod)%mod;
return 0;
}`
P8557 炼金术(Alchemy)
显而易见,对于每一种矿物,至少需要分配到一个熔炉, 方案数为总集减去空集,即 。 而一共有 个矿物,每个矿物有 种方案, 所以答案就是 代码:
#include
using namespace std;
#define int long long
const int mod=998244353;
int n,k;
int mi(int x,int y){
int ans=1;
while(y){
if(y%2) ans*=x,ans%=mod;
y/=2,x=x*x%mod;
}
return ans%mod;
}
signed main(){
cin>>n>>k;
cout
`#include
using namespace std;
#define int long long
const int mod=998244353;
int n,k;
int mi(int x,int y){
int ans=1;
while(y){
if(y%2) ans*=x,ans%=mod;
y/=2,x=x*x%mod;
}
return ans%mod;
}
signed main(){
cin>>n>>k;
coutmi((mi(2,k)-1),n);
return 0;
}`
P6298 齿轮
首先统计每个齿数的出现频率 , 并预处理组合数 用于快速计算。 接着对于每个数 , 统计所有齿数为 的倍数的齿轮个数 , 这表示最大公约数是 的倍数的候选齿轮数。 然后利用容斥原理,从大到小计算 , 这样 就表示最大公约数恰好为 的方案数。 最后输出 到 即为所有损耗因子的答案。 代码:
#include
using namespace std;
#define int long long
const int N=1e6+5;
const int mod=1e9+7;
int n,m,k;
int a[N],ans[N],t[N],f[N],j[N],jj[N];
int mi(int x,int y){
int ans=1;
while(y){
if(y%2) ans*=x,ans%=mod;
y/=2,x=x*x%mod;
}
return ans;
}
int C(int x,int y){
if(xy) return 0;
return j[y]*jj[x]%mod*jj[y-x]%mod;
}
signed main(){
cin>>n>>m>>k;
for(int i=1;i>a[i];
t[a[i]]++;
}
j[0]=jj[0]=1;
for(int i=1;i=1;i--){
ans[i]=C(k,f[i]);
for(int j=i*2;j
`#include
using namespace std;
#define int long long
const int N=1e6+5;
const int mod=1e9+7;
int n,m,k;
int a[N],ans[N],t[N],f[N],j[N],jj[N];
int mi(int x,int y){
int ans=1;
while(y){
if(y%2) ans*=x,ans%=mod;
y/=2,x=x*x%mod;
}
return ans;
}
int C(int x,int y){
if(x0||y0||x>y) return 0;
return j[y]*jj[x]%mod*jj[y-x]%mod;
}
signed main(){
cin>>n>>m>>k;
for(int i=1;i
cin>>a[i];
t[a[i]]++;
}
j[0]=jj[0]=1;
for(int i=1;i
j[i]=j[i-1]*i%mod;
jj[i]=mi(j[i],mod-2);
}
for(int i=1;i
for(int j=i;j
f[i]+=t[j];
}
}
for(int i=m;i>=1;i--){
ans[i]=C(k,f[i]);
for(int j=i*2;j
ans[i]=(ans[i]-ans[j]+mod)%mod;
}
}
for(int i=1;ians[i]" ";
return 0;
}`