您的位置:首页 > 其它

HDU -- 4135 Co-prime【质因子分解+状压 + 容斥定理】+ 模板

2017-08-07 15:46 387 查看
传送门

//问l,r中和n互质的数有几个. 即gcd(n,k) == 1的有多少个元素.

//思路 : 分解n的质因子, 然后用容斥定理算每一区间中可以整除这个质因子的有几个.

AC Code

/** @Cain*/
vector<ll >v;
ll rongchi(ll x,ll n)   //就算1-x中与n互素的数的个数.
{
v.clear();
for(ll i=2;i*i<=n;i++){
if( n%i == 0){
while( n%i == 0) n /= i;
v.push_back(i);
}
}
if( n != 1) v.push_back(n);

//用二进制来1,0来表示第几个素因子是否被用到,如size=3, 三个因子是2,3,5
//则i=3时二进制是011, 表示第2,3个因子被用到,类似状态压缩.
//size最大10左右. 枚举出所有的因子可能的组合性.
ll sum = 0;
for(ll i=1;i<(1<<v.size());i++){ //二进制枚举所有可能
ll tmp = 1,cnt = 0;
for(ll j = 0;j<v.size();j++){
//我们不仅要知道该个二进制有多少位1,并且还要具体知道是在
//哪一位上有1. 这样我们才可以知道当前枚举了哪些质因子.
//所以这个枚举的姿势要选好.!!!
if(i&(1<<j)){
//记住j里面始终都只有一个1.这样我们不仅可以知道当前的i有多少
//为1,并且具体是在那些位上.
tmp *= v[j];
cnt++;
}
}
if(cnt%2) sum += x/tmp;  //容斥原理,奇加偶减
else sum -= x/tmp;
}
return x-sum;  //最后返回区间长度-不满足的数.
}

void solve()
{
ll l,r,n;
scanf("%lld%lld%lld",&l,&r,&n);
printf("Case #%d: ",cas++);
printf("%lld\n",rongchi(r,n) - rongchi(l-1,n));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: