容斥原理主要是应用因子的组合形式(也就是Ai的并)。
在区间范围中就是先求含有两个因子的最小数,也就是最小公倍数。r/lcm(a,b) 也就是(1,r)中含有z这个数的个数。
奇加偶减。
模板为计算(1,r)中 与num互质/非互质的个数。
二进制:
void getfactor(__int64 num)
{
fac.clear();
for(int i=2;i*i<=num;i++)
{
if(num%i==0)
{
fac.push_back(i);
while(num%i==0)num/=i;
}
}
if(num>1)fac.push_back(num);
}
__int64 coprime(__int64 num,__int64 r)
{
int mm=(1<<fac.size());
__int64 ans=0;
for(int i=1;i<mm;i++)
{
int cnt=0;__int64 temp=1;
for(int j=0;j<fac.size();j++)
{
if(i&(1<<j))
{
cnt++;
temp*=fac[j];<span style="font-family: Arial, Helvetica, sans-serif;">//这里其实是公倍数,因为二者互质所以为相乘</span>
}
}
if(cnt&1)
ans+=r/temp;
else ans-=r/temp;
}
return r-ans;
}
dfs法:
int cnt=0;
void getfac(int x)
{
cnt=0;
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
{
p[cnt++]=i;
while(x%i==0)x/=i;
}
}
if(x>1)p[cnt++]=x;
}
void dfs(int idx,int num,int val,int R)
{
if(idx==cnt)
{
if(val==1)return;
if(num&1)x+=R/val;
else x-=R/val;
return;
}
dfs(idx+1,num+1,val*p[idx],R);//这里其实是公倍数,因为二者互质所以为相乘
dfs(idx+1,num,val,R);
}
hdu 4135
给定[l,r],n,求与n互质的数的个数。
poj 2773
给定 m,k
求与m互质的第k个数。
hdu 5072
给n个数。
求三个数(两两互质或两两不互质)的组合数量。
hdu 1796
给定n,m={a1,…,am}.
求1~n中被m集合任意一个数整除的数的个数。
hdu 1695
给定 (1,b),(1,d),求gcd(x,y)=k的对数。x属于(1,b),y属于(1,c)
hdu 2841
给定m*n矩阵,起点为(0,0),与起点形成一条直线的上的树中只能看见第一颗。
hdu 3501
所有n的因子(除1外)的和。也就是非互质的数的和。