HDU - 2814 Visible Trees

Title: 

  In the forest of m*n (1<=m, n<=100000), the starting point is (1, 1), someone starts from the (0, 0) point and asks how many trees can be seen.

answer:

  Find the sum of each number in 1~x and the coprime number in the numbers 1~y. Use a sieve of prime numbers to filter out prime numbers within 1e5. Use these primes to sieve out the prime factors of each number within 1e5. Finally, the number that is coprime to each number is calculated by inclusion and exclusion.

#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 vis[maxn];
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);
    }
}
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324400728&siteId=291194637