HDU-2841-Visible Trees(容斥)

31 篇文章 0 订阅

HDU-2841-Visible Trees

传送门

这道题是容斥哟~这个地方我用的是队列数组(其实容斥实现的地方dfs或者位运算均可)
先开始是在容斥的知识点看到写的=-=后来卡了许久,又换到莫比乌斯反演上面去看,最后还是回到容斥上面去了。

题目大意:农夫夏洛克站在坐标为(0,0)的位置,他去看一个每个网格点都种了树的m*n的网格。问可以看到多少棵树,其中如果有两颗以上的树与夏洛克在同一条直线上,那么夏洛克只能看到一棵树。

本题思路:这道题转换过来其实就是让我们求在区间[1, m]与[1, n]这些数里面(i, j)其中i与j互质的对数有多少。
根据题目意思:在与夏洛克在同一条直线上面的树只能看到一棵,也就是斜率相等的看不见。所以转换过来就是让我们求互质的数有多少对了。
这道题的思路跟HDU 4135差不多,代码其实也差不多,可以直接参考HDU 4135的博客,然后这道题的思路我就不多说啦:

https://blog.csdn.net/qq_44624316/article/details/105972702

我们首先用埃筛来线性得到质数。a[]数组:a[i]得到的是i的质因数。
埃筛的博客参考:https://blog.csdn.net/qq_44624316/article/details/105431013

然后我们再把[2, n]跑一遍,直接用容斥来计算互质的对数有多少,维护答案ans就行~,记得使用ll。
ans初始化为m,m代表行数,我们在循环遍历的时候是一列一列的计算的,第一列的树是我们全部可以看到的,所以就是上面初始化的原因。
q[]数组就是我们的队列数组啦~
cal()函数就是计算每列哪些树可以看到的,返回的是可以看到的树的数目,(就是互质的对数)

代码部分:

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e5 + 10;

int m, n;
ll ans;
vector<int> a[N];
int q[N];

void init()
{
	for (int i = 0; i < N; i++)
	{
		a[i].clear();
	}
	for (int i = 2; i < N; i++)
	{
		int t = i;
		for (int j = 2; j * j <= i; j++)
		{
			if (!(t % j))
			{
				a[i].push_back(j);
				while (!(t % j))
				{
					t /= j;
				}
			}
		}
		if (t > 1)
		{
			a[i].push_back(t);
		}
	}
}

ll cal(int x, int s)
{
	int num = 0;
	q[num++] = 1;
	int siz = a[s].size();
	for (int i = 0; i < siz; i++)
	{
		int t = a[s][i];
		if (t > x)
		{
			break;
		}
		int k = num;
		for (int j = 0; j < k; j++)
		{
			q[num++] = q[j] * t * (-1);
		}
	}
	ll sum = 0;
	for (int i = 0; i < num; i++)
	{
		sum += x / q[i];
	}
	return sum;
}

int main()
{
	init();
	int t;
	cin >> t;
	while (t--)
	{
		cin >> m >> n;
		ans = m;
		for (int i = 2; i <= n; i++)
		{
			ans += cal(m, i);
		}
		cout << ans << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

娃娃酱斯密酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值