您的位置:首页 > 其它

hdu1695((容斥定理+欧拉函数)或(莫比乌斯反演))

2015-08-19 16:05 260 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1695

容斥定理+欧拉函数:

详解:/article/8652147.html

Yoiu can assume that a = c = 1 in all test cases.(最后这句真的是。。。。。。)

#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <queue>
#include <set>
#include <stack>
using namespace std;
#define N 100005
int q
;
bool vis
;
int f
,phi
;
vector<int>vt
;

void Eular(){
phi[1]=1;
int k,num=0;
memset(vis,0,sizeof(vis));
for(int i=2;i<N;i++){
if(!vis[i]){f[num++]=i;phi[i]=i-1;}
for(int j=0;j<num&&(k=i*f[j])<N;j++){
vis[k]=true;
if(i%f[j]==0){
phi[k]=phi[i]*f[j];break;
}else phi[k]=phi[i]*(f[j]-1);
}//for_j
}//for_i
}
void init(){
for(int i=2;i<N;i++){
int t=i;
for(int j=0;f[j]*f[j]<=i;j++)if(t%f[j]==0){
vt[i].push_back(f[j]);
while(t%f[j]==0) t/=f[j];
}//for_j
if(t>1) vt[i].push_back(t);
}//for_i
}
long long cal(int n,int s){
int num=0;
q[num++]=1;
for(int i=0;i<vt[s].size();i++){
int ep=vt[s][i];
if(ep>n) break;
int k=num;
for(int j=0;j<k;j++) q[num++]=q[j]*ep*(-1);
}//for_i
long long sum=0;
for(int i=0;i<num;i++) sum+=n/q[i];
return sum;
}
int main(){
int a,b,c,d,k;
int T,t=0;
Eular();
init();
scanf("%d",&T);
while(T--){
t++;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
if(k==0||k>b||k>d){
printf("Case %d: 0\n",t);
continue;
}//_if
b/=k;d/=k;
if(b>d) swap(b,d);
long long ans=0;
for(int i=1;i<=b;i++) ans+=phi[i];
for(int i=b+1;i<=d;i++) ans+=cal(b,i);
printf("Case %d: %lld\n",t,ans);
}//while
return 0;
}


莫比乌斯反演:/article/8623745.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: