link
T1 三值的排序
Problem
给出一个长为 n 的、仅含 1,2,3 的序列 ai,求排序所需的最小交换次数(不要求相邻)。
100%→n≤1000
1s/128MB
Solution
提前预处理每个数值有几个,然后扫一遍所有 1 应当在的位置:
- 如果扫到 1,不管。
- 如果扫到 2,扫 2 应当在的位置。
-
-
- 如果没扫到,扫在 3 应当在的位置,交换,答案 +1。
- 如果扫到 3,类似于 2。
然后扫一遍 2 应当在的位置,操作类似于 1。
时间复杂度 O(n2)。
Summary
出现了经典的复制下来然后后面忘了改后面的情况,100pts→90pts。
T2 日记
Problem
求不超过 n 的数中能表示成连续个 k个的质数的和的最大数,无解输出 −1,多测。
100%→1≤T<2000,1≤n≤106,1≤k≤109
1s/128MB
Solution
质数筛提前预处理质数做前缀和,然后对于每次询问二分质数中的位置,用差分查询区间和看有没有超过 n。
时间复杂度 O(n+Tlog(primesize−k))
Summary
100pts
T3 切蛋糕
Problem
圆形蛋糕被切成 n 块,每块蛋糕有权值 ai,A 先手拿蛋糕,然后 B, A 交替拿一块已拿蛋糕相邻的蛋糕,但 B 会拿权值最大的那一块,而 A 可以随意选择,最大化 A 拿到的蛋糕权值和,有 Subtask。
100%→1≤n≤2000,1≤ai≤109,ai are unique
2s/512MB
Solution
先断环成链复制一倍,显然可选蛋糕只能是已选蛋糕的两端,这样就可以做区间 DP。
设 fi,j 为 A 先手获得的最大权值和,然后枚举 A 的选择来转移 B 的选择:
- A 选择左边的蛋糕:
-
- ai+1>aj→fi,j=maxfi+2,j+ai B 之后会选择左边的蛋糕。
-
- ai+1<aj→fi,j=maxfi+1,j−1+ai B 之后会选择右边的蛋糕。
- A 选择右边的蛋糕:
-
- ai>aj−1→fi,j=maxfi+1,j−1+aj B 之后会选择左边的蛋糕。
-
- ai<aj−1→fi,j=maxfi,j−2+aj B 之后会选择右边的蛋糕。
记搜转移即可,答案为 maxfi,i+n−1。
时间复杂度 O(n2)。
Summary
爆搜写挂了,考虑到是区间 DP 了转移想不出来了,没想到记搜,寄寄。 0pts
T4 都市
Problem
给出 2n(n−1) 个数 bi,为长度为 n 的原序列 ai 的两两数的和,求出所有可能的解。
解的顺序按字典序从大到小排序,解内的数按从小到大排序。
100%→1≤n≤300,1≤ai≤108
1s/128MB
Solution
排序,显然 b1=a1+a2,b2=a1+a3,然后在 bi 中枚举 a2+a3,把这三个数删了,剩下的数中最小的肯定为 a1+a4,通过 b1,b2,b3 能把 ai 求出来,然后枚举前面的数看 a4+ai 在不在 bi 出现过,若没出现显然这个 a2+a3 的方案不行,若出现就删掉,这样剩下的数中最小的又为 a1+a5,以此类推。
怎么快速删数、找最小的数、看某个数是否出现过?std::multiset<int>
! STLの力は無限大です
时间复杂度 O(n2logn)。
Summary
你猜题面有的地方为什么加粗(虽然我写的爆搜) 0pts。
T5 街灯
Problem
给出长度为 n 的序列 ai,m 次询问区间 [l,r] 中,aimodp=v 的个数,其中 p,v 每次询问时给出,无修。
30%→1≤n,m≤103
another 30%→p are the same
100%→1≤n,m≤105,0≤ai≤104,1≤p≤109
1s/128MB
Solution
30 分暴力,60 分莫队,也可以直接用下面 p>100 的做法。这才是设置这档分的目的吧
考虑到 ai 的值域比较小,提前将每个数的位置加入到这个数中的 vector 中,然后考虑根号分治:
- p≤100:提前将每个数模 1∼100 以内的数的结果所对应的位置全加到对应模数和余数所对应的另一个 vector 中,询问的时候二分一下 vector 内部,区间差分一下结果就行了。
- p>100:满足 aimodp=v 的数至多有 100 个,考虑暴力枚举 v,p+v,2p+v…,然后和 p≤100 一样的方式查询答案,不过是对一开始预处理的那个 vector 二分。
n,m 同阶时时间复杂度 O(nnlogn)。
Summary
莫队赢麻了。