1.容斥原理
举例:A∪B∪C=A+B+C-A∩B-A∩C-B∩C+A∩B∩C;
ll solve(ll x)
{
ll ans = 0;
for(ll i=1;i<=totle;i++)
{
int se=1,cnt=0;
for(int j=0;j<m;j++)
{
if((i>>j)&1) se *= f[j],cnt++;
}
if(cnt&1) ans += x/se;
else ans -= x/se;
}
return x-ans;
}
其中total和m是
vector<int>f;
f.clear();
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
f.push_back(i);
while(n%i==0) n /= i;
}
}
if(n!=1) f.push_back(n);
m = f.size();
totle = (1<<m)-1;
例题:
给定一个整数n,和区间[l,r],问区间中有多少整数和n互素,即与n的最大公约数为1。
你能帮他解决这个问题吗?
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int solve(ll r, ll n) {
vector<int>p;
p.clear();
for(int i = 2; i*i <= n; ++i) {
if(n % i == 0) {
p.push_back(i);
while(n % i == 0) n /= i;
}
}
if(n > 1) p.push_back(n); //可能n也是素数
int sum = 0;
for(int msk = 1; msk < (1<<p.size()); ++msk) {
int mult = 1, bits = 0;
for(int i = 0; i < p.size(); ++i) {
if(msk & (1<<i)) { //选择了第i个素数因子
bits++;
mult *= p[i];
}
}
int cur = r / mult;
if(bits & 1) sum += cur;
else sum -= cur;
}
return r - sum;
}
int main()
{
ios::sync_with_stdio(0);
int T,t;
ll l,r,n;
cin>>T;
for(int i=1;i<=T;i++)
{
cin>>l>>r>>n;
t=solve(r,n)-solve(l-1,n);
cout<<"Case #"<<i<<": "<<t<<endl;
}
return 0;
}