其他分享
首页 > 其他分享> > Mnnu第三场天梯选拔赛

Mnnu第三场天梯选拔赛

作者:互联网

Mnnu第三场天梯选拔赛

A.

原题链接

点我跳转

题目大意

给$n$个数,求出所有数对的最小公倍数的最大公约数

解题思路

我们对于某个数$a_i$,只要看它和区间$[i+1,n]$的每个数的最小公倍数,因为前面的部分会由前面的数和$a_i$去组合,我们不用重复计算。假如要求$a$对$b$、$c$的$lcm$ 的$gcd$ ,$gcd(ab/gcd(a,b),ac/gcd(a,c))$ ,相当于$agcd(b/gcd(a,b),c/gcd(a,c))$, 实际上就是$agcd(b,c)/gcd(a,b,c)$,所以我们可以考虑一手求后缀的gcd,依次转移。

解题代码

#include<bits/stdc++.h>
#define int long long
#define ios std::ios::sync_with_stdio(false)
#define rep(i,a,n) for (int i=a;i<=n;i++)

using namespace std;

const int N = 2e5 + 10, MOD = 1e9+7, inf = 0x3f3f3f3f;
int a[N], g[N];
signed main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	g[n] = a[n];
	g[n - 1] = __gcd(a[n], a[n - 1]);
	int res = a[n] / g[n - 1] * a[n - 1];
	for (int i = n - 2; i >= 1; i--){
		g[i] = __gcd(g[i + 1], a[i]);
		res = __gcd(res, a[i] / g[i] * g[i + 1]);
	}
	cout << res << '\n';
    return 0;
}

D.

原题链接

点我跳转

题目大意

解题思路

与该行互质的点会被直接观察到,计算出第$i$行的互质数的个数,即求欧拉函数,累计求和。

过题代码

#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define int long long

using namespace std;

const int N = 2e5 + 10, MOD = 1e9+7, inf = 0x3f3f3f3f;
int vis[N],prime[N],phi[N],len,ans;
signed main()
{
	int n;
	cin >> n;
	if (n == 1) return cout << 0 << '\n',0;
	for (int i = 2; i <= n; i++){
		if (!vis[i]){
			prime[++len] = i;
			phi[i] = i - 1;
		}
		for (int j = 1; j <= len; j++)
		{
			if (prime[j] * i > n) break;
			vis[prime[j] * i] = 1;
			if (i % prime[j] != 0)
				phi[i * prime[j]] = phi[i] * (prime[j] - 1);
			else{
				phi[i * prime[j]] = phi[i] * prime[j];
				break;
			}
		}
	}
	for (int i = 2; i <= n- 1; i++)
		ans += phi[i];
	cout << ans * 2 + 3 << '\n';
    return 0;
}

M.

原题链接

点我跳转

题目大意

给出$n$个区间,$q$个查询区间,问每次查询时,该查询区间内有多少个点至少被$k$个区间覆盖。

解题思路

使用差分数组+前缀和

生成差分数组:a[l]++ , a[r+1]--

前缀和a[i] += a[i-1]

这样处理之后,a[i] 表示 i 这个数符合多少个区间。

sum[i] 逐个记录答案,最后$O(1)$查询答案。

解题代码

#include<bits/stdc++.h> 
#define ios std::ios::sync_with_stdio(false)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define int long long

using namespace std;

const int N = 2e5 + 10, MOD = 1e9+7, inf = 0x3f3f3f3f;
int a[N],sum[N];
signed main()
{
	int m,k,q;
	cin >> m >> k >> q;
	for (int i = 1; i <= m; i++){
		int l,r;
		cin >> l >> r;
		a[l]++, a[r + 1]--;
	}
	for (int i = 1; i < N; i++){
		a[i] += a[i - 1];
		sum[i] = (a[i] >= k? sum[i - 1] + 1 : sum[i - 1]);
	}
	while(q--){
		int l,r;
		cin >> l >> r;
		cout << sum[r] - sum[l - 1] << '\n';
	}
    return 0;
}

标签:prime,long,gcd,int,Mnnu,--,选拔赛,第三场,define
来源: https://www.cnblogs.com/zhengyongjin/p/13865787.html