count_prime
Time Limit: 1000ms
Memory Limit: 65536KB
Input
第一行输入一个整数T(1 <= T <= 100),表示T组测试数据。接下来T行,每行3个整数a,b,n(1 <= a <=b <=10^15, 1<= n <= 10^9),用空格隔开。
Sample Output
5
6
搞了一个多小时,终于弄懂了QAQ,容斥原理。
1-i中,是a的倍数和b的倍数的个数为i/a+i/b-i/(a*b)。
设有n个因子,求 1-i中这n个因子的倍数的个数。
定义变量k,从1开始,for到n,每for一次,任取k个因子相乘,如果是奇数个因子,就把当前值加上i/(k个因子的积),否则减去。
dfs
cur代表当前的因子,now代表当前的乘积,neg代表奇或偶,mid代表i,res代表结果
6
搞了一个多小时,终于弄懂了QAQ,容斥原理。
1-i中,是a的倍数和b的倍数的个数为i/a+i/b-i/(a*b)。
设有n个因子,求 1-i中这n个因子的倍数的个数。
定义变量k,从1开始,for到n,每for一次,任取k个因子相乘,如果是奇数个因子,就把当前值加上i/(k个因子的积),否则减去。
dfs
cur代表当前的因子,now代表当前的乘积,neg代表奇或偶,mid代表i,res代表结果
f代表元素个数,fac代表因子数组0-(f-1)
void dfs(ll cur,ll now,bool neg,ll mid,ll &res){
if(cur>=f)return;
ll num=now*fac[cur]/gcd(now,fac[cur]);//这里是最小公倍数 不然会出错 比如是6或8的倍数且小于等于24 如果不是最小公倍数就会少减一个24
dfs(cur+1,now,neg,mid,res);//搜不放这个因子的积
if(neg)res=res+mid/num;
else res=res-mid/num;
dfs(cur+1,num,!neg,mid,res);//搜放这个因子的积
}
#include<iostream>
#include<stdio.h>
using namespace std;
typedef long long ll;
ll t,n,a,b,i,x,flag,sum,fac[105],f;
ll gcd(ll a,ll b){
if(b==0)return a;
return gcd(b,a%b);
}
void dfs(ll cur,ll now,bool neg,ll mid,ll &res){
if(cur>=f)return;
ll num=now*fac[cur]/(gcd(now,fac[cur]));
dfs(cur+1,now,neg,mid,res);
if(neg)res=res+mid/num;
else res=res-mid/num;
dfs(cur+1,num,!neg,mid,res);
}
int main(){
cin>>t;
while(t--){
cin>>a>>b>>n;
f=0;
ll so=0;
for(i=2;n!=1;i++){
while(n%i==0){
if(so!=i){
fac[f++]=i;
}
so=i;
n/=i;
}
}
ll res=0;
dfs(0,1,1,a-1,res);
ll so1=a-1-res;
res=0;
dfs(0,1,1,b,res);
ll so2=b-res;
cout<<so2-so1<<endl;
}
return 0;
}