您的位置:首页 > 其它

容斥原理之素数部分模板

2014-11-01 14:25 281 查看
容斥原理主要是应用因子的组合形式(也就是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外)的和。也就是非互质的数的和。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: