HDU - 2814 Visible Trees
Posted Pneuis
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 2814 Visible Trees相关的知识,希望对你有一定的参考价值。
题意:
m*n(1<=m,n<=100000)的森林里,起始点在(1,1),某人从(0,0)点开始看,问能看到多少棵树。
题解:
求出1~x中的每个数与1~y的数中互质的数的总和。用素数筛筛出1e5以内的素数。在用这些素数筛出1e5以内每个数的素数因子。最后通过容斥算出与每个数互质的个数。
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <cmath> using namespace std; typedef long long ll; const int maxn = 1e5+10; int t; int x, y; int len; int pnum; int p[maxn]; bool e[maxn]; ll res, ans; vector<int> g[maxn]; void prime() { e[0] = e[1] = 1; pnum = 0; for(int i = 2; i < maxn; i++) { if(e[i]==0) p[++pnum] = i; for(int j = 1; j<=pnum && p[j]*i<maxn; j++) { e[p[j]*i] = 1; if(i%p[j]==0) break; } } } int gcd(int x, int y) { return y==0?x:gcd(y, x%y); } int lcm(int x, int y) { return x/gcd(x, y)*y; } void dfs(int cur, int tol, int sum, int id) { if(cur >= len) return ; int p = lcm(g[id][cur], sum); if(tol&1) res -= y/p; else res += y/p; dfs(cur+1, tol+1, p, id); dfs(cur+1, tol, sum, id); } int main() { prime(); for(int i = 1; i <= pnum; i++) { int cnt = 1; while(cnt*p[i] <= 100000) { g[cnt*p[i]].push_back(p[i]); cnt++; } } scanf("%d", &t); while(t--) { scanf("%d%d", &x, &y); if(x > y) swap(x, y); ans = y; for(int i = 2; i <= x; i++) { res = 0; len = g[i].size(); dfs(0, 0, 1, i); ans += y-res; } printf("%lld\n", ans); } }
以上是关于HDU - 2814 Visible Trees的主要内容,如果未能解决你的问题,请参考以下文章