zoukankan      html  css  js  c++  java
  • hdu 1695 GCD

    // 题意: 给你区间[a,b] [c,d] 在两个区间各取一个数x,y,要求gcd(x,y)= k
    // 题目给的区间中说  0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000,
    // 真是不知道简便方法 后面看到 Yoiu can assume that a = c = 1 in all test cases. a,c是永远等于1的
    // 于是 相当于求 区间[1,b/k]和区间[1,d/k]中 互质数的对数
    // 假设 b<d 那么 b/k以前的就 sigmaphi[1..b/k] phi指的是欧拉函数
    // 大于 b/k 的每个数就用容斥原理进行操作
    #include <iostream> #include <string> #include<sstream> #include <cmath> #include <map> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define LL __int64 //#define LL long long #define N 100010 struct node { int cnt; int pr[10]; }hs[N]; LL phi[N]; LL ans; void init() { int i,j; for(i=1;i<N;i++) phi[i]=i; for(i=2;i<N;phi[i]+=phi[i-1],i++ ) if(phi[i]==i) { for(j=i;j<N;j+=i) { phi[j]=phi[j]/i*(i-1); hs[j].pr[hs[j].cnt]=i; hs[j].cnt++; } } // printf("%I64d == ",phi[4]); } int b,d,k; void dfs(int deep,int n,int index,int val) { int t; for(int i=index;i<hs[n].cnt;i++) { t=val*hs[n].pr[i]; if(deep&1) ans=ans-(b/t); else ans=ans+(b/t); dfs(deep+1,n,i+1,t); } } int main() { int T; init(); scanf("%d",&T); for(int c=1;c<=T;c++) { scanf("%d %d %d %d %d",&b,&b,&d,&d,&k); // if(k==0){ printf("Case %d: 0 ",c);continue; } if(b>d) swap(b,d); b/=k; d/=k; // printf("%d %d",b,d); //ans=0; ans=phi[b]; for(int a=b+1;a<=d;a++){ ans+=b; dfs(1,a,0,1); // printf("%I64d ? ",ans); } printf("Case %d: %I64d ",c,ans); } return 0; }
  • 相关阅读:
    快速幂模板
    部分有关素数的题
    POJ 3624 Charm Bracelet (01背包)
    51Nod 1085 背包问题 (01背包)
    POJ 1789 Truck History (Kruskal 最小生成树)
    HDU 1996 汉诺塔VI
    HDU 2511 汉诺塔X
    HDU 2175 汉诺塔IX (递推)
    HDU 2077 汉诺塔IV (递推)
    HDU 2064 汉诺塔III (递推)
  • 原文地址:https://www.cnblogs.com/372465774y/p/3619666.html
Copyright © 2011-2022 走看看