2024校计算机大赛题解
比赛链接:
比赛时间:2024.11.17
U503552 村庄的友谊
在一个遥远的村庄里,村民们的契合度是一个重要的特征。每个村民都有一个契合度,契合度的值为 $1$ 到 $n$ 之间的任意整数。村民们之间的友谊是基于他们的契合度:只有当两个村民的契合度相乘的结果是质数时,他们才能成为朋友,否则他们就是陌生人,即使他们可能有相同的朋友。
现在,村庄的长老希望了解村庄中有多少对不同的陌生人。请你帮助长老计算出来。
输入格式
- 第一行输入一个整数 $n\ (1 ≤ n ≤ 5*10^5)$,表示村民的数量。
- 第二行输入 $n$ 个整数,表示每个村民的契合度,契合度的值在 $1$ 到 $5*10^5$ 之间。
输出格式
输出一个整数,表示村庄中有多少对不同的陌生人。
数据范围
对于 $20%$ 的数据,$1 <= n <= 10$
对于 $40%$ 的数据,$1 <= n <= 1000$
对于 $100%$ 的数据,$1 <= n <= 500000$
题解:
一个质数只能被1和它本身整除。因此,如果两个村民的契合度相乘为质数,则其中一个村民的契合度必须为1,另一个村民的契合度必须为这个质数。契合度为1的村民与其他所有质数的村民都是朋友。
- 统计契合度为1的村民数量
countOnes
。- 统计契合度不为1的村民数量
countprime
。- 计算陌生人对数:陌生人对数 = 总对数 - 朋友对数。
- 总对数可以通过组合公式
C(n, 2) = n * (n - 1) / 2
计算。- 朋友对数等于契合度为1的村民与其他所有非1的村民之间的配对数,即
count_ones * countprime
。
1 |
|
U504030 再多一些0
小T有一个数 $n$,现在他可以从 $[1,m]$ 中选一个数字 $k$,然后把 $n$ 变成 $kn$ ,由于小T非常喜欢数字0,所以他下意识的认为一个数的后缀0个数越多越好,请你找到一个最大的 $k$ ,使得 $kn$ 的后缀0个数最多。
后缀0个数:就是指一个数字末尾有多少个0,例如1992000这个数字末尾有3个0,所以它的后缀0个数就为3。
输入格式
输入两个正整数 $n,m$。
输出格式
输出一个整数,表示能选到的最大 $k$。
样例 #1
样例输入 #1
1 | 5 43 |
样例输出 #1
1 | 40 |
提示
样例解释
在本题中,当 $k=40$ 时得到 $5 \times 40 = 200$,此时后缀0数量最多且 $k$ 最大。
数据范围
对于$100%$的数据,$1 \le n,m \le 10^9$。
2和5相乘为10,每有一对2和5则多一个0。
若n中有a个2,b个5,则n中后缀0的数量为min(a, b)(a, b的较小值)。
因为m最大为10^9,枚举[1, m]中的每个数作为k显然会超时。
考虑枚举k中有多少个2和多少个5,因为在10^9内,一个数最多含有log_2 10^9个2或者log_5 10^9个5,数量不会很多,所以这样枚举不会超时。
如果当前枚举k中有c个2和d个5,k*n的后缀0个数为min(a+c, b+d)。
按题目要求保留取后缀0最多的,且最大的k即为答案。
1 |
|
U505285 开光灯
题目描述
现在有$n$个灯泡排成一行,分别编号$ 1 $ ~ $ n $,灯泡默认都是关闭的,而小T手速惊人,他每次可以选择一个区间$ [l,r] $,然后改变这区间内的所有灯泡的状态,如果此时灯泡是打开的,则变关闭,否则从关闭变打开。现在你已经知道小T进行了$ m $次操作,但小$ T $想考考你,如果此时小$ T $第$ i $个操作不执行的话,此时多少盏灯泡是打开的。
输入格式
第一行 两个整数$ n ,m $ 表示灯泡的数量和小$ T $操作的次数。
接下来$ m $行,每行两个整数$ l,r $ 表示小$ T $操作的区间。
输出格式
一行$ m $个数字,每个数字之间用空格隔开,表示小$ T $第$ i $个操作不执行的话此时打开着的灯泡数。
样例 #1
样例输入 #1
1 | 5 2 |
样例输出 #1
1 | 3 5 |
样例 #2
样例输入 #2
1 | 10 4 |
样例输出 #2
1 | 3 6 3 5 |
提示
第一个样例,当第一个操作不做时,此时只有$2,3,4$打开着,故答案为$3$,当第二个操作不做时,此时灯全部打开着,故答案为$5$。
数据规模与约定
保证所有测试点$ 1\le l \le r \le n $。
对于$ 20%$的数据 , 保证 $1 \le n, m \le 500 $,并且每个操作中$ l $和$ r $都相等,即操作的都是同一段区间,不保证$ l = r $。
对于$ 60%$的数据 , 保证 $ 1 \le n, m \le 5000 $。
对于 $100 %$ 的数据,保证$1 \le n, m \le 10^6 $。
解决这个问题,我们需要采用一种高效的方法来处理大量的查询和更新操作。直接模拟每个操作会超时,因为最坏情况下时间复杂度可能达到𝑂(𝑛×𝑚)O(n×m),这在给定的数据范围内是不可接受的。因此,我们考虑使用差分数组的思想来优化我们的算法。
解题思路
- 初始化差分数组:创建一个长度为𝑛+2n+2的差分数组
diff
,用来记录每个位置的变化情况。额外的两个位置是为了避免边界条件的特殊处理。- 应用所有操作:遍历每个操作,根据操作的区间[𝑙,𝑟][l,r]对差分数组进行更新。具体来说,增加
diff[l]
,减少diff[r+1]
。这样做的目的是为了标记区间的开始和结束,方便后续计算每个位置的实际状态。- 计算最终状态:通过前缀和的方式计算每个位置的最终状态。这一步需要遍历差分数组,累加值来确定每个灯泡是否开启。
- 模拟移除每个操作:再次遍历每个操作,假设当前操作没有发生,重新计算差分数组,并根据更新后的差分数组计算新的灯泡状态。统计开启的灯泡数量,并将结果存储起来。
- 输出结果:最后输出存储的结果。
实现细节
- 使用一个额外的变量来记录当前开启的灯泡总数,以便快速计算移除某个操作后的影响。
- 在模拟移除每个操作时,只需调整该操作对差分数组的影响,然后基于当前的开启灯泡总数和受影响的区间长度来计算新的开启灯泡数。
1 |
|