FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a ,y<=b,并且gcd(x,y)=d。作为FGD的同学,FGD希望得到你的帮助。
标签:inline min name zoj 关系 wap span 预处理 data
FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a ,y<=b,并且gcd(x,y)=d。作为FGD的同学,FGD希望得到你的帮助。
第一行包含一个正整数n,表示一共有n组询问。(1<=n<= 50000)接下来n行,每行表示一个询问,每行三个 正整数,分别为a,b,d。(1<=d<=a,b<=50000)
对于每组询问,输出到输出文件zap.out一个正整数,表示满足条件的整数对数。
#pragma GCC optimize("O2") #include <cstdio> #include <algorithm> using namespace std; char buf[10000000], *ptr = buf - 1; inline int readint(){ int n = 0; while(*++ptr < ‘0‘ || *ptr > ‘9‘); while(*ptr <= ‘9‘ && *ptr >= ‘0‘) n = (n << 1) + (n << 3) + (*ptr++ & 15); return n; } const int maxn = 50000 + 10; bool mark[maxn] = {false}; int mu[maxn], sum[maxn]; int pri[maxn], prn = 0; void shai(){ mu[1] = 1; for(int i = 2; i <= 50000; i++){ if(!mark[i]){ pri[++prn] = i; mu[i] = -1; } for(int j = 1; j <= prn && pri[j] * i <= 50000; j++){ mark[i * pri[j]] = true; if(i % pri[j] == 0){ mu[i * pri[j]] = 0; break; } else mu[i * pri[j]] = -mu[i]; } } sum[0] = 0; for(int i = 1; i <= 50000; i++) sum[i] = sum[i - 1] + mu[i]; } int a, b, d; inline void work(){ a = readint(); b = readint(); d = readint(); a /= d; b /= d; if(a > b) swap(a, b); int ans = 0, pos; for(int i = 1; i <= a; i = pos + 1){ pos = min(a / (a / i), b / (b / i)); ans += (sum[pos] - sum[i - 1]) * (a / i) * (b / i); } printf("%d\n", ans); } int main(){ fread(buf, sizeof(char), sizeof(buf), stdin); shai(); int n = readint(); while(n--) work(); return 0; }
标签:inline min name zoj 关系 wap span 预处理 data
原文地址:http://www.cnblogs.com/ruoruoruo/p/7630019.html