赞
踩
整理的算法模板合集: ACM模板
实际上是一个全新的精炼模板整合计划
怎么这么多人AK呀 … 确实挺简单的 (●ˇ∀ˇ●) 考到了很多常用技巧,一堆智商检测题,简直好评hhh
不过怎么全是签到题呀,确实比较考察思维hhh但是比赛过的人却很少 ~ 以前前几题都是能过一万五来着,这次只有几千…
比赛链接:https://codeforces.com/contest/1485
Problem A Add and Divide
Translation
给定两个正整数 a a a, b b b ,你可以进行两种操作:
请问最少多少次操作,使得 a = 0 a=0 a=0。
Word
Solution
签到题 ~
之前做过这种题目,链接:2021年洛谷一月月赛(Div1、Div2,6题)全部题解 C题,比这个难多了 ~
但是万变不离其宗,那道题同样有两个操作,加一或者 × 2 \times 2 ×2 ,最小费用修改,使得整个序列满足一个条件,需要套一个二分加DP。
中心思想还是分析性质。我们发现 + + + 操作前期比 × \times × 收益更大,后期 × \times × 操作比 + + + 操作收益更大,由于乘的话是指数级增长,所以那么数据是 1 0 9 10^9 109 ,实际的操作次数也是常数级别的,所以我们可以暴力。这道题仅要求将 a a a 除到 0 0 0,我们仅需将 b b b 加到 10 10 10 即可,然后暴力计算。
其实可以简单地证明一下,为什么到 10 10 10 一定ok,实际上一次加操作,最后的总贡献是你乘的次数,如果当你乘一次的贡献就已经超过了乘的次数,也就是说乘的贡献此时一定超过了加的贡献,所以简单算一下,我们发现 log 10 1 0 9 = 9 \log_{10}10^9=9 log10109=9, 所以只需要加到10即可 ~
Code
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long ll; typedef int itn; const int N = 5007; const ll INF = 4e18; int n, m, t; ll a, b; void solve() { scanf("%lld%lld", &a, &b); if(a == 0) { puts("0"); return ; } ll res = INF, ans; ll cnt = 0; ll B = b; if(b == 1) b ++ , cnt ++ ; for(; b <= 10; ++ b) { ans = 0; cnt ++ ; ll tmp_a = a; while(tmp_a) { tmp_a /= b; ans ++ ; } ans += cnt; ans -- ; if(ans < res) res = ans; } if(B > 10) { ans = 0; while(a) { a /= B; ans ++ ; } } res = min(res, ans); printf("%lld\n", res); return ; } int main() { scanf("%d", &t); while(t -- ) { solve(); } }
Problem B Replace and Keep Sorted
Translation
对于一个正整数 k k k ,规定两个序列是 “ k k k 相似序列” 需要满足以下要求:
给定一个正整数 k k k,一个严格递增的序列 a a a ,将会有 q q q 次询问,每次询问一个区间 l l l , r r r ,你的任务是每次输出有多少种 b b b 序列是序列 a l , a l + 1 , a l + 2 ⋯ , a r a_l,a_{l+1},a_{l+2}\cdots,a_r al,al+1,al+2⋯,ar 的 “ k k k 相似序列” 。
Word
Solution
签到题 ~
注意一个重要的性质:严格递增
因为元素的取值只能是 [ 1 , k ] [1,k] [1,k] ,并且两个序列必须只能有一个不同的元素,由于序列一定严格递增,求总的方案数,实际上对于每一个序列来说,每次只能有一个位置不同,而对于这个位置来说,手算一下发现,对于每一个区间里的数,一共有 a [ i + 1 ] − a [ i − 1 ] − 2 a[i+1]-a[i-1]-2 a[i+1]−a[i−1]−2 种选法,对于区间的边界来说,一共有 a [ i + 1 ] − a [ i − 1 ] − 2 a[i+1]-a[i-1]-2 a[i+1]−a[i−1]−2 种选法,设每一个位置 i i i 的选法就是 i i i 的权值,由加法原理可知,总方案数就是区间权值和,所以我们直接使用一个前缀和维护一下即可。
Code
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long ll; typedef int itn; const int N = 2e5 + 7; const ll INF = 4e18; int n, m, t, q, k; ll val[N], a[N]; ll sum[N]; int main() { scanf("%d%d%d", &n, &q, &k); for(int i = 1; i <= n; ++ i) { scanf("%d", &a[i]); } a[0] = 1, a[n + 1] = k; for(int i = 1; i <= n; ++ i) { val[i] = a[i + 1] - a[i - 1] - 2; sum[i] = sum
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。