Educational Codeforces Round 72 (Rated for Div. 2)
Solutaion
A. Creating a Character
题意:
给出初始体力值\(str\)和智力值\(int\),然后你可以把\(exp\)分别分配给这两个数值,使得分配后\(str > int\),求有多少种分配方案。
思路:
- 特判不可能情况:\(str + exp <= int\)
- \(str <= int\),乱搞
- \(str > int\),乱搞
正解:
假设分别分配给\(str,int\)的数值为\(Adds,Addi\),那么有
\[ \begin{align*} & str + Adds > int + Addi \\ {\Rightarrow}{\quad} & str + Adds > int + (exp - Adds)\\ {\Rightarrow}{\quad} &2{\ast}Adds > int + exp - str\\ {\Rightarrow}{\quad} &2{\ast}Adds\ {\geq}\ int + exp - str + 1\\ {\Rightarrow}{\quad} &Adds\ {\geq}\ {\lceil}{\frac{int + exp - str + 1}{2}}{\rceil}\\ {\Rightarrow}{\quad} &Adds\ {\geq}\ {\frac{int + exp - str + 1 + 1}{2}} \end{align*} \]
因为非负,所以\(Adds=max(0,{\frac{int + exp - str + 2}{2}})\),定义这个值为\(minAdds\),分配值的区间为\([minAdds,exp]\),那么答案为\(ans=max(0,exp - minAdds + 1)\)。
//#define DEBUG
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const int inf = 0X3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int mod = 1000000007;
typedef long long ll;int _;
int main() {#ifdef DEBUGfreopen("in.txt", "r", stdin);#endiffor (scanf("%d", &_); _; _--) {ll str, intt, exp;scanf("%lld %lld %lld", &str, &intt, &exp);if (str + exp <= intt) puts("0");else if (str <= intt) {ll x = exp - (intt - str);printf("%lld\n", x % 2 ? x / 2 + 1 : x / 2);} else {if (intt + exp - str < 0) printf("%lld\n", exp + 1);else {ll x = (intt + exp - str) / 2 + 1;printf("%lld\n", exp - x + 1);}}}
}
//#define DEBUG
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const int inf = 0X3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int mod = 1000000007;
typedef long long ll;int _;
int main() {#ifdef DEBUGfreopen("in.txt", "r", stdin);#endiffor (scanf("%d", &_); _; _--) {int st, in, ex, tmp;scanf("%d %d %d", &st, &in, &ex);tmp = max(0, (in + ex - st + 2) / 2);printf("%d\n", max(ex - tmp + 1, 0));}
}
B. Zmei Gorynich
题意:
让你斩杀多头蛇,给出头数\(x\)和你可以斩杀的类型\(n\)。每种类型包含两个数\(d,h\),代表每次斩杀能斩掉\(d\)个头,如果没死的话,他会长出\(h\)个头。问最少斩杀次数。
思路:
首先,如果第一次用最大“毛斩杀”可以杀死就结束了,如果不能杀死,就用最大“纯斩杀”来斩。
//#define DEBUG
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const int inf = 0X3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int mod = 1000000007;
typedef long long ll;int _;
int main() {#ifdef DEBUGfreopen("in.txt", "r", stdin);#endiffor (scanf("%d", &_); _; _--) {int m, n;scanf("%d %d", &m, &n);int val = -inf, maxx = -inf;while (m--) {int u, v;scanf("%d %d", &u, &v);val = max(val, u - v);maxx = max(maxx, u);}ll ans = 1;n -= maxx;if (n > 0) {if (val <= 0) ans = -1;else ans += (n + val - 1) / val;}printf("%lld\n", ans);}
}
C. The Number Of Good Substrings
题意:
假定\(f(t)=val\),其中\(t\)为\(01\)字符串,\(val\)为其代表的二进制值,比如\(f(011)=3,f(00101) = 5\)。给出一个\(01\)字符串,求有多少个子串使得\(f(s_l,s_{l+1},{\dots},s_r) = r - l + 1\)
思路:
因为字符串长度不超过\(2e5\),所以可以每次枚举20位去判断。预处理出\(nxt[i]\),表示\(1{\dots}i\)中最后一个\(1\)的位置,\(nxt[i]=-1\)。枚举\(i\)前\(20\)位,定义\(sum\)为当前长度子串所代表的二进制的值。如果当前\(sum<=r-nxt[l]\),贡献\(+1\)。
//#define DEBUG
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const int inf = 0X3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int mod = 1000000007;
typedef long long ll;int _;
char s[2 * N];
int nxt[2 * N];int main() {#ifdef DEBUGfreopen("in.txt", "r", stdin);#endiffor (scanf("%d", &_); _; _--) {scanf("%s", s);int len = strlen(s);for (int i = 0; i < len; i++) {if (s[i] == '0') nxt[i] = (i == 0 ? -1 : nxt[i - 1]);else nxt[i] = i;}int ans = 0;for (int i = 0; i < len; i++) {int sum = 0;for (int j = i; j >= 0 && i - j + 1 <= 20; j--) {if (s[j] == '0') continue;sum += 1 << (i - j);if (sum <= i - (j == 0 ? -1 : nxt[j - 1]))ans++;}}printf("%d\n", ans);}
}
D. Coloring Edges
题意:
给出\(n\)个点\(m\)条边的有向图,然后给边染色,用最少种类的颜料,使得环上的边不是纯色。求最少种类。
思路:
画出图可以分析出,不存在环显然一种即可。若存在环,最多需要两种颜料。在发现环的时候换色即可。好像之前做过类似的题目。但是比赛时没有看这个题。\(dfs\)先一次标记该点,用颜料1一直染边,如果遇到某点被一次标记,说明存在环,该边染为颜料2。如果遇到二次标记点,该边染为颜料1。
//#define DEBUG
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const int inf = 0X3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int mod = 1000000007;
typedef long long ll;vector<pair<int, int> > G[5010];
int n, m;
int colour[5010];
int res[5010];
bool flag;void dfs(int u) {colour[u] = 1;for (auto it : G[u]) {int to = it.first, id = it.second;if (!colour[to]) {res[id] = 1;dfs(to);} else if (colour[to] == 1) {res[id] = 2;flag = true;} else {res[id] = 1;}}colour[u] = 2;
}int main() {#ifdef DEBUGfreopen("in.txt", "r", stdin);#endifflag = false;scanf("%d %d", &n, &m);for (int i = 1; i <= m; i++) {int u, v;scanf("%d %d", &u, &v);G[u].push_back(make_pair(v, i));}for (int i = 1; i <= n; i++) {if (!colour[i]) dfs(i);}if (flag) puts("2");else puts("1");for (int i = 1; i <= m; i++) printf("%d%c", res[i], i == m ? '\n' : ' ');
}
E. Sum Queries?
题意:
如果集合内元素右对齐放置,对应位出现的数字之和不等于对应位的非\(0\)数字,则说明该可重复元素集合是\(unbalanced\)。换句话说,就是如果放置后,对应位的数字有两个非\(0\)数字,就说明\(unbalanced\)。可单点修改某一位置的值,求每次询问区间的不平衡集合的最小和。
思路:
就是区间找两个对应位都不为\(0\)的数字,然后求最小和。因为\(a_i{\leq}10^9\)网上都是说开\(10\)棵线段树,我不是很理解这个说法,把数字\(x\)拆分开。如果某位数字不为0,就设为\(x\),否则设为\(inf\),然后维护每一位的最小值,维护答案。初始为\(inf\),单点更新和建树差不多。\(pushup\)操作就\(Min[rt][i]\)为左右儿子的对应的最小值,\(val[rt]\)就是左右儿子对应为都不为\(inf\)时的和,同时也是左右儿子的答案的最小值。\(query\)操作用\(res[i]\)保存这次查询历史对应位的最小值,然后\(ans=min(ans,res[i]+Min[rt][i])\),每次再更新\(res[i]\)。用我的\(inf\)会WA5,小于\(2e9\)。
//#define DEBUG
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const int inf = 0X3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int mod = 1000000007;
typedef long long ll;ll val[2 * N * 4], Min[2 * N * 4][15];
int a[2 * N];
int n, m;
ll res[15];
ll ans;void pushup(int rt) {val[rt] = INF;for (int i = 0; i <= 12; i++) {if (Min[rt << 1][i] != INF && Min[rt << 1 | 1][i] != INF) {val[rt] = min(val[rt], Min[rt << 1][i] + Min[rt << 1 | 1][i]);}Min[rt][i] = min(Min[rt << 1][i], Min[rt << 1 | 1][i]);}val[rt] = min(val[rt], min(val[rt << 1], val[rt << 1 | 1]));
}void build(int l, int r, int rt) {val[rt] = INF;if (l == r) {int tmp = a[l];for (int i = 0; i <= 12; i++) {int x = tmp % 10;if (x == 0) Min[rt][i] = INF;else Min[rt][i] = a[l];tmp /= 10;}return ;}int mid = l + r >> 1;build(l, mid, rt << 1);build(mid + 1, r, rt << 1 | 1);pushup(rt);
}void modify(int pos, int x, int l, int r, int rt) {if (l == r) {int tmp = x;for (int i = 0; i <= 12; i++) {int y = tmp % 10;if (y == 0) Min[rt][i] = INF;else Min[rt][i] = x;tmp /= 10;}return ;}int mid = l + r >> 1;if (pos <= mid) modify(pos, x, l , mid, rt << 1);else modify(pos, x, mid + 1, r, rt << 1 | 1);pushup(rt);
}void query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) {for (int i = 0; i <= 12; i++) {if (Min[rt][i] != INF && res[i] != INF) {ans = min(ans, Min[rt][i] + res[i]);}}for (int i = 0; i <= 12; i++) {res[i] = min(res[i], Min[rt][i]);}ans = min(ans, val[rt]);return ;}int mid = l + r >> 1;if (L <= mid) query(L, R, l, mid, rt << 1);if (R > mid) query(L, R, mid + 1, r, rt << 1 | 1);
}int main() {#ifdef DEBUGfreopen("in.txt", "r", stdin);#endifscanf("%d %d", &n, &m);for (int i = 1; i <= n; i++) scanf("%d", &a[i]);build(1, n, 1);while (m--) {int op, l, r, pos, x;scanf("%d", &op);if (op == 1) {scanf("%d %d", &pos, &x); modify(pos, x, 1, n, 1);} else {scanf("%d %d", &l, &r);ans = INF;for (int i = 0; i <= 12; i++) res[i] = INF;query(l, r, 1, n, 1);printf("%lld\n", ans == INF ? -1 : ans);}}
}
转载于:https://www.cnblogs.com/ACMerszl/p/11517315.html
Educational Codeforces Round 72 (Rated for Div. 2)相关推荐
- Educational Codeforces Round 72 (Rated for Div. 2) D. Coloring Edges dfs树/拓扑找环
传送门 文章目录 题意: 思路: 题意: 给你一张图,你需要给这个图的边染色,保证如果有环那么这个环内边的颜色不全相同,输出染色方案和用的颜色个数. n,m≤5e3n,m\le5e3n,m≤5e3 思 ...
- Educational Codeforces Round 90 (Rated for Div. 2)(A, B, C, D, E)
Educational Codeforces Round 90 (Rated for Div. 2) Donut Shops 思路 分三种情况: a==c/ba == c / ba==c/b这个时候两 ...
- Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Educational Codeforces Round 114 (Rated for Div. 2) ...
- Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 Educational Codeforces Round 106 (Rated for Div. ...
- Educational Codeforces Round 37 (Rated for Div. 2) 1
Educational Codeforces Round 37 (Rated for Div. 2) A.Water The Garden 题意:Max想给花园浇水.花园可被视为长度为n的花园床,花园 ...
- Educational Codeforces Round 89 (Rated for Div. 2)(A, B, C, D)
Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords 思路 题意非常简单,就是得到最多的物品嘛,我们假定a, ...
- Educational Codeforces Round 114 (Rated for Div. 2) D. The Strongest Build 暴力 + bfs
传送门 文章目录 题意: 思路: 题意: 你有nnn个装备槽,每个槽里面有cic_ici个力量加成,对于每个槽只能选一个力量加成,现在给你mmm个力量组合[b1,b2,...,bn][b_1,b_2 ...
- Educational Codeforces Round 111 (Rated for Div. 2) D. Excellent Arrays 组合数学
传送门 文章目录 题意: 思路: 题意: 给你一个数组aia_iai,定义一个数组是好的当且仅当对于所有iii都有ai!=ia_i!=iai!=i.定义f(a)f(a)f(a)表示数组aaa中i& ...
- Educational Codeforces Round 111 (Rated for Div. 2) E. Stringforces 二分 + 状压dp
传送门 文章目录 题意: 思路: 题意: 给你一个串,只包含前kkk个字母和???,定义fif_ifi表示第iii个字母在串中出现的最长连续长度,你现在需要将???替换为前kkk个字母,使得mini ...
最新文章
- GitHub 的AI代码生成神器,其四成代码有漏洞,你还敢用吗
- 苹果开发之Cocoa编程(原书第4版)
- web嵌入到原生的app里需要注意的事项
- 关于Android 中 一个错误的解决办法 “Do not request Window.FEATURE_ACTION_BAR.....
- ORCU浅析之安装和作用
- Pytorch——用50行代码搭建ResNet
- 【数据结构】天勤 例2-3 (单链表归并操作)二、递减
- 微计算机控制器功能是什么意思,微型计算机中,控制器的基本功能是().
- 强化理解指针、指针数组和数组指针(从三味书屋到成华大道)
- LeetCode精选TOP面试题(中等篇)【出现率降序】
- 【题解】【PTA-Python题库】第6章-7 找出总分最高的学生 (15 分)
- Html网页制作图片选择
- [学习笔记]后缀数组
- C++数据结构第13课、类族结构的进化
- 用技术致敬每一位妈妈,B站up主用AI还原李焕英老照片动态影像
- @Aspect aop切面获取请求接口类名、方法名、及参数
- 西门子PLC学习笔记六-(Step7指令简介)
- 机房收费系统(六)-结账
- 网络工程师精选习题详解(二)
- php如何放照片,如何在PHP会话中存储照片上传?
热门文章
- 每天一道LeetCode-----计算最长的元素连续序列长度
- 每天一道LeetCode-----将链表中满足条件的节点移动到前面
- Outlook另类小技巧 批量处理图片大小
- Windows 注册表开机启动总结
- 设计进步,记一笔,控制层的代码,他不光控制还要校验数据!以前理解错啦
- 第九届河南理工大学算法程序设计大赛 正式赛(ABCDEFGHJKL)
- vector中的圆括号和花括号
- Linux下内存问题检测神器 valgrind
- 数理统计-5.4 三大抽样分布
- [BUUCTF-pwn]——wdb_2018_2nd_easyfmt