每次都能咕一周才写博客
咕哉咕哉
T1
【题目描述】
给出
N
N
N个整数
A
1
,
.
.
.
,
A
N
A_1,...,A_N
A1,...,AN,请你计算
A
1
×
.
.
.
×
A
N
A_1×...×A_N
A1×...×AN 的值。如果计算结果超过
1
0
18
10^{18}
1018,则输出
−
1
-1
−1。
约束条件:
2
≤
N
≤
1
0
5
2≤N≤10^5
2≤N≤105
0
≤
A
i
≤
1
0
18
0≤Ai≤10^{18}
0≤Ai≤1018
输入的所有值都是整数。
【 S o l Sol Sol】
读入时判断是否有 0 0 0,有 0 0 0则一定为 0 0 0。判断是否超过 1 0 18 10^{18} 1018时,不要直接相乘判断,用 a ∗ b > c a*b>c a∗b>c等价于 a > b / c a>b/c a>b/c转换即可(当时没想到,于是用 u n s i g n e d l o n g l o n g unsigned\ long\ long unsigned long long被卡到 95 95 95…)
C o d e Code Code
T2
【题目描述】
给定正整数
N
(
1
≤
N
≤
1
0
12
)
N(1≤N≤10^{12})
N(1≤N≤1012)。
请考虑在
N
N
N上重复应用以下两步操作:
(1)首先,选择满足以下所有条件的正整数
z
z
z:
z
z
z可以表示为
z
=
p
e
z=p^e
z=pe,其中
p
p
p是质数,
e
e
e是正整数;
z
z
z能整除
N
N
N(即:
N
N
N除以
z
z
z的结果为整数) ;
z
z
z不同于先前操作中选择过的所有整数。
(2)然后,用
N
/
z
N/z
N/z替换
N
N
N。
任务:问最多可以进行多少次这样的操作。
【 S o l Sol Sol】
将
N
N
N表示为
N
=
z
1
∗
z
2
∗
z
3
∗
⋯
∗
z
n
,
z
i
=
p
i
e
i
N=z_1*z_2*z_3*\dots*z_n,z_i={p_i}^{e_i}
N=z1∗z2∗z3∗⋯∗zn,zi=piei,手玩不难发现就是将
e
i
e_i
ei表示为
k
i
k_i
ki个不同数的和,答案就是
∑
i
=
1
n
k
i
\sum^{n}_{i=1}k_i
∑i=1nki。
注意点:1.因为在处理时能处理成
p
i
p_i
pi的一定是质数(若有因数前面已经判断过了,不可能还剩有前面因数的倍数),所以不用每次判断是否
i
s
p
r
i
m
e
(
p
)
=
=
1
isprime(p)==1
isprime(p)==1(一开始每个都判断,差点
T
T
T去世
…
\dots
…)2.不能用
2
∗
e
i
\sqrt{2*e_i}
2∗ei(
e
i
=
5
e_i=5
ei=5时就挂了),直接按照答案要求模拟就行了。3.
N
N
N被所有符合条件的素数整除后,可能结果不为
1
1
1,此时答案
a
n
s
+
+
ans++
ans++,需要特判一下。
C o d e Code Code
T3
【题目描述】
T
o
m
Tom
Tom决定从明天开始,在给定的
N
N
N天里面,选择
K
K
K天出来工作。
给定一个整数
C
C
C和一个字符串
S
S
S(每天对应一个字符),
T
o
m
Tom
Tom的工作日选择如下:
(1)工作一天后,他将不再在随后的
C
C
C天工作。
(2)如果
S
S
S的第
i
i
i个字符是
x
x
x,则他不会在第
i
i
i天工作。其中的第
1
1
1天就是明天,第
2
2
2天是后天,依此类推。
请你编程找出
T
o
m
Tom
Tom必须要工作的所有日子。
如果没有必须工作的日子,则什么都不输出。
【 S o l Sol Sol】
考虑贪心
首先倒着循环每次能工作的天,然后正着循环每次能工作的天,两次循环后重合的点就是必须要工作的天。
f r o m from from题解:
倒着循环每次最早能上班的时刻上班,然后找 c c c天后的不是 x x x的天;
然后正着循环做一遍。
如果两遍都要某一个点的话那个点就是答案。这是因为这两遍分别是 T o m Tom Tom上班的左区
间和右区间,只要这个区间最后聚在一个点,这一天就是确定的一天。
C o d e Code Code
T4
【题目描述】
老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才
有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为
10
10
10,要求在
6
6
6天内交,那么要想拿到这
10
10
10学分,就必须在第
6
6
6天结束前交。
每个作业的完成时间都是只有一天。例如,假设有7次作业的学分和完成时间如下:
作业号
1
2
3
4
5
6
7
1 \ 2\ 3 \ 4 \ 5\ 6 \ 7
1 2 3 4 5 6 7
期 限
1
1
3
3
2
2
6
1 \ 1 \ 3\ 3 \ 2 \ 2\ 6
1 1 3 3 2 2 6
学 分
6
7
2
1
4
5
1
6 \ 7 \ 2 \ 1\ 4 \ 5 \ 1
6 7 2 1 4 5 1
最多可以获得
15
15
15学分,其中一个完成作业的次序为
2
,
6
,
3
,
1
,
7
,
5
,
4
2,6,3,1,7,5,4
2,6,3,1,7,5,4,注意可能
还有其他方法。
你的任务就是找到一个完成作业的顺序获得最大学分。
【 S o l Sol Sol】
贪心+并查集
贪心是一个比较典型的模型了,并查集也是常规指向操作。
(1)算法1:贪心策略
本题类似带限期和罚款的单位时间任务调度(另外见“智力大冲浪”)
[题目模型]
有n个任务,每个任务都需要1个时段去执行,任务i的截止时间di(1≤di≤n)表
示要求任务i在时间段di必须完成,误时惩罚wi表示若任务i未在时间段di及之前完成,
将导致wi的罚款。确定所有任务的执行顺序,使得惩罚最少。
[思路点拨]
要使惩罚最少,我们显然应尽量先完成wi值较大的任务。
将任务按wi从大到小进行排序,然后按照排好的顺序依次对任务进行安排。安排的规
则为:使得处理任务i的时间既在1~di之内,又尽量靠后(即从di倒着往前尝试);如果
1~di范围之内的时间都已经安排,则放弃处理该任务,接受惩罚。
(2)算法2:二叉堆(大根堆)
逆向思维我们发现:可以从后往前往每一天插入“作业”。
首先将作业按期限从大到小排序,从最后一天开始安排作业,安排到第i天时,加入
期限截止至第i天的所有作业,之后取出未做过的学分最大的作业安排在第i天做。
很容易想到用堆来实现加入作业和取学分最大值的操作,相当于第i天时堆内的作
业,就是放在第i天可以得到学分的作业。
按学分从高到低排序,然后顺序的选择结束时间,从这个时间一直往前找,直到找到一个没有用过的时间点,此时用掉这个时间即可(标记),采用并查集来找,首先祖先都指向自己,自己被占用后指向前一个没有被占有的点,回溯标记即可。
C o d e Code Code
T5
【问题描述】
给出一张
n
n
n个点,
m
m
m条边的无向图,摧毁每条边都需要一定的体力,并且花费的体力值各不相同,给定图中两个点
x
,
y
(
x
≠
y
)
x,y(x≠y)
x,y(x=y),每当
(
x
,
y
)
(x,y)
(x,y)之间存在路径,就需要不断摧毁当前图中花费体力最少的一条边,直到该路径不联通。他定义
c
o
s
t
(
x
,
y
)
cost(x,y)
cost(x,y)为摧毁
(
x
,
y
)
(x,y)
(x,y)之间路径花费的体力和。
他想要求出以下这个结果:
(
∑
1
≤
i
,
j
≤
n
c
o
s
t
(
i
,
j
)
)
%
1
0
9
(\sum\limits_{1\leq {i,j} \leq n}cost(i,j) ) \%10^9
(1≤i,j≤n∑cost(i,j))%109 其中
i
,
j
∈
n
i,j∈n
i,j∈n,并且
i
<
j
i<j
i<j 。
【 S o l Sol Sol】
先理解题意:对于每个点都要进行删边操作,于是删边的边权要乘上当前两个联通块中所有的点对数量。
本题与星球大战类似。从小到大删边就是从大到小加边,加到使现在处理的这两个点联通的边就是将边权值小于等于这个边的边全部删去。于是不难想到排两次序,第一次预处理前缀和,第二次处理加边操作。
C o d e Code Code
记得多取几次模,开 l o n g l o n g long\ long long long