HDU - 2814 Visible Trees
2024-08-24 22:24:54
题意:
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+;
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[] = e[] = ; pnum = ;
for(int i = ; i < maxn; i++) {
if(e[i]==) p[++pnum] = i;
for(int j = ; j<=pnum && p[j]*i<maxn; j++) {
e[p[j]*i] = ;
if(i%p[j]==) break;
}
}
}
int gcd(int x, int y) {
return y==?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&) res -= y/p;
else res += y/p;
dfs(cur+, tol+, p, id);
dfs(cur+, tol, sum, id);
}
int main() {
prime();
for(int i = ; i <= pnum; i++) {
int cnt = ;
while(cnt*p[i] <= ) {
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 = ; i <= x; i++) {
res = ;
len = g[i].size();
dfs(, , , i);
ans += y-res;
}
printf("%lld\n", ans);
}
}
最新文章
- tracert与pathping
- cf 731f
- NuGet多个项目依赖的公共组件如何打包
- HTML学习笔记——选择器
- 泊松回归(Poisson Regression)
- map 后 PE 蓝屏原因专题讨论(e820cycles参数)
- ylbtech-Unitity-CS:Generics
- Direct2D 简介
- php 二维码生成类
- C语言顺序栈实现
- 8086 CPU 寻址方式
- POJ 1159 - Palindrome 优化空间LCS
- C# 6.0:Auto-Property initializer
- idea实现热部署并且开启自动编译
- Deep Dive into Spark SQL’s Catalyst Optimizer(中英双语)
- 多项式函数插值:多项式形式函数求值的Horner嵌套算法
- 笔记三:python乱码深度剖析一
- DICOM 协议学习笔记之 What is DICOM
- JIT IR,C2
- web 安全问题(一):CSRF 攻击