CF Round #510 (Div. 2)
前言:没想到那么快就打了第二场,题目难度比CF Round #509 (Div. 2)这场要难些,不过我依旧菜,这场更是被\(D\)题卡了,最后\(C\)题都来不及敲了。。最后才\(A\)了\(3\)题,幸好\(Rating\)没掉。
A. Benches
Description
有\(n\)个位置,给出每个位置上原本有\(a[i]\)个人。现有\(m\)个人,把他们安排到这\(n\)个位置上,设安排完后位置上人数最多的位置有\(k\)个人,求最大的\(k\)和最小的\(k\)。
Solution
官方正解复杂度为\(O(mn)\)
而我机房里有大佬写了二分答案的做法(传送门)
这里给出我的\(O(n)\)做法。
最大值显然就是\(n\)个位置上原有的最多的人数加上\(m\)。
对于最小值,其实就是去填\(n\)个位置,使得每个位置的人数尽量平均,设原有最多人数为\(maxn\),则一共可以填\(\sum\limits_{i=1}^n maxn-a[i]\)个人。
若填完后没有剩余,则答案就是\(maxn\);若有剩余,则将剩余的人平均分配到\(n\)个位置即可。
#include<cstdio>
#include<cmath>
using namespace std;
const int N = 110;
int a[N];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline int maxn(int x, int y)
{
return x > y ? x : y;
}
int main()
{
int i, n, m, ma = 0, s = 0;
n = re();
m = re();
for (i = 1; i <= n; i++)
{
a[i] = re();
ma = maxn(ma, a[i]);
}
for (i = 1; i <= n; i++)
s += ma - a[i];
if (s >= m)
printf("%d %d", ma, ma + m);
else
printf("%d %d", ma + (int)ceil(1.0 * (m - s) / n), ma + m);
return 0;
}
B. Vitamins
Description
有\(n\)杯果汁,每个果汁需要花费\(a[i]\),同时会提供维生素,维生素有\(ABC\)三种类型,而每种果汁会提供其中的几种维生素,而\(Petya\)希望获得\(ABC\)三种维生素,求达成目标的最小花费。
Solution
我机房里的大佬写的和正解是一样的(传送门)
而我写了个记忆化搜索,算是玄学复杂度,不过也能过。
对于维生素的储存可以使用压位的方法,并在搜索中记录在已经获得某些维生素的最小花费即可。
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1010;
int a[N], b[N], f[10], n;
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline char re_l()
{
char c = getchar();
for (; c != 'A' && c != 'B' && c != 'C' && c != '\n' && c != '\r' && c > 0; c = getchar());
return c;
}
void dfs(int x, int nw, int se)
{
int i;
if (nw > f[se])
return;
f[se] = nw;
for (i = x; i <= n; i++)
if ((se | b[i]) ^ se)
dfs(i + 1, nw + a[i], se | b[i]);
}
int main()
{
int i, k = 0;
char c;
n = re();
for (i = 1; i <= n; i++)
{
a[i] = re();
while (1)
{
c = re_l();
if (c != 'A' && c != 'B' && c != 'C')
break;
if (c == 'A')
b[i] |= 1;
else
if (c == 'B')
b[i] |= 1 << 1;
else
b[i] |= 1 << 2;
}
k |= b[i];
}
if (k ^ 7)
{
printf("-1");
return 0;
}
memset(f, 60, sizeof(f));
dfs(1, 0, 0);
printf("%d", f[7]);
return 0;
}
C. Array Product
Description
给出一个有\(n\)项的序列\(a\), 有两种操作
- 选择两个数\(a_i, a_j\),把\(a_j\)更新为\(a_i\times a_j\), 将\(a_i\)删去
- 直接删去数\(a_i\) ( 该种操作最多只能进行\(1\)次)
求如何操作才能使\(n-1\)次操作后剩下的那个数最大, 输出操作的方案。
Solution
比赛时因为被\(D\)题卡了,所以没来得及打,赛后才\(A\)的。
显然正数可以忽略,考虑负数和\(0\),有\(4\)种情况。
- 奇数个负数,存在\(0\)。将\(0\)和绝对值最小的负数相乘,才删去得到的\(0\),剩下的全部乘起来。
- 奇数个负数,不存在\(0\)。直接删去\(0\),剩下的全部乘起来。
- 偶数个负数,存在\(0\)。将所有\(0\)乘起来并删去最后得到的\(0\),剩下的全部乘起来。
- 偶数个负数,不存在\(0\)。直接全部乘起来。
#include<cstdio>
#include<cstring>
#include<set>
#include<algorithm>
using namespace std;
const int N = 2e5 + 10;
int ze[N], zer, k;
set<int>se;
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
void dze()
{
int i;
for (i = 2; i <= zer; i++)
{
se.erase(ze[i - 1]);
printf("1 %d %d\n", ze[i - 1], ze[i]);
}
if (se.size() ^ 1)
{
se.erase(ze[zer]);
printf("2 %d\n", ze[zer]);
}
}
void alc()
{
int x, s = se.size();
while (s ^ 1)
{
set<int>::iterator it = se.begin();
x = *it;
++it;
printf("1 %d %d\n", x, *it);
se.erase(x);
s--;
}
}
int main()
{
int i, x, n, ma = -1e9, o, fsh = 0;
n = re();
for (i = 1; i <= n; i++)
{
x = re();
if (x < 0)
{
++fsh;
if (ma <= x)
{
ma = x;
o = i;
}
}
else
if (!x)
ze[++zer] = i;
se.insert(i);
}
if (fsh & 1 && zer)
{
printf("1 %d %d\n", o, ze[zer]);
se.erase(o);
dze();
}
else
if (fsh & 1)
{
printf("2 %d\n", o);
se.erase(o);
}
else
if (zer)
dze();
alc();
return 0;
}
D. Petya and Array
Description
给出一个含\(n\)个数的序列\(a\),和一个数\(t\),求序列中有多少区间满足\(\sum\limits_{i=l}^{r}a_i<t\)
Solution
求一个后缀和,将问题转化为有多少个子段满足\(S[j]-S[i+1]<t\rightarrow S[j]<t+S[i+1]\),枚举\(i\),前面的和用数据结构维护即可。
机房大佬写的是求前缀和,再用树状数组求逆序对维护,道理是差不多的(传送门)
而我比较菜,直接去把我的平衡树板子复制过来,实时插入并求排名来维护。
不过我的\(Splay\)板子出了奇怪的锅,导致在这题上浪费很多时间,还未通过\(4\)次,最后一气之下换了\(Treap\)板子,然后才\(A\)了。。
另外,因为我写平衡树板子的时候没有打空格的习惯,所以代码显得很奇怪。。
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
struct trp{
ll l,r,s,v,si,rd;
};
trp tr[N];
ll S[N], ro, nu, an;
int a[N];
inline ll re()
{
ll x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
void pp(ll r)
{
tr[r].si=tr[tr[r].l].si+tr[tr[r].r].si+tr[r].s;
}
void rt(ll& r)
{
ll k=tr[r].l;
tr[r].l=tr[k].r;
tr[k].r=r;
tr[k].si=tr[r].si;
pp(r);
r=k;
}
void lt(ll& r)
{
ll k=tr[r].r;
tr[r].r=tr[k].l;
tr[k].l=r;
tr[k].si=tr[r].si;
pp(r);
r=k;
}
void is(ll& r,ll x)
{
if(!r)
{
r=++nu;
tr[r].v=x;
tr[r].s=tr[r].si=1;
tr[r].rd=rand();
return;
}
tr[r].si++;
if(tr[r].v==x)
tr[r].s++;
else
{
if(tr[r].v<x)
{
is(tr[r].r,x);
if(tr[tr[r].r].rd<tr[r].rd)
lt(r);
}
else
{
is(tr[r].l,x);
if(tr[tr[r].l].rd<tr[r].rd)
rt(r);
}
}
}
void qu_fo(ll r,ll x)
{
if(!r)
return;
if(tr[r].v<x)
{
an=r;
qu_fo(tr[r].r,x);
}
else
qu_fo(tr[r].l,x);
}
ll qu_rk(ll r,ll x)
{
if(!r)
return 0;
if(tr[r].v==x)
return tr[tr[r].l].si+tr[r].s;
if(tr[r].v<x)
return tr[tr[r].l].si+tr[r].s+qu_rk(tr[r].r,x);
return qu_rk(tr[r].l,x);
}
ll qu_nu(ll r,ll x)
{
if(!r)
return 0;
if(x<=tr[tr[r].l].si)
return qu_nu(tr[r].l,x);
else
if(x>tr[tr[r].l].si+tr[r].s)
return qu_nu(tr[r].r,x-tr[tr[r].l].si-tr[r].s);
return tr[r].v;
}
int main()
{
srand(20021113);
int i, n;
ll m, qj = 0, j;
n = re();
m = re();
for (i = 1; i <= n; i++)
a[i] = re();
for (i = n; i; i--)
S[i] = S[i + 1] + a[i];
for (i = 1; i <= n; i++)
{
is(ro, S[i]);
an = -1e18;
qu_fo(ro, m + S[i + 1]);
if (an == -1e18)
continue;
j = tr[an].v;
qj += qu_rk(ro, j);
}
printf("%I64d", qj);
return 0;
}
CF Round #510 (Div. 2)的更多相关文章
- CF Round #551 (Div. 2) D
CF Round #551 (Div. 2) D 链接 https://codeforces.com/contest/1153/problem/D 思路 不考虑赋值和贪心,考虑排名. 设\(dp_i\ ...
- Codeforces Round #510 (Div. 2)
Codeforces Round #510 (Div. 2) https://codeforces.com/contest/1042 A 二分 #include<iostream> usi ...
- 竞赛题解 - CF Round #524 Div.2
CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...
- CF Round #600 (Div 2) 解题报告(A~E)
CF Round #600 (Div 2) 解题报告(A~E) A:Single Push 采用差分的思想,让\(b-a=c\),然后观察\(c\)序列是不是一个满足要求的序列 #include< ...
- cf Round#273 Div.2
题目链接,点击一下 Round#273 Div.2 ================== problem A Initial Bet ================== 很简单,打了两三场的cf第一 ...
- 【codeforces】【比赛题解】#960 CF Round #474 (Div. 1 + Div. 2, combined)
终于打了一场CF,不知道为什么我会去打00:05的CF比赛…… 不管怎么样,这次打的很好!拿到了Div. 2选手中的第一名,成功上紫! 以后还要再接再厉! [A]Check the string 题意 ...
- CF Round #509 (Div. 2)
前言:第一次打\(CF\),因为经验不足以及英语水平很烂,即便在机房大佬的带领下也是花了好久才读懂题目..\(A\)题直到\(11\)分钟才\(A\),题目一共才做了\(4\)题,太菜了.. A. H ...
- 【codeforces】【比赛题解】#937 CF Round #467 (Div. 2)
没有参加,但是之后几天打了哦,第三场AK的CF比赛. CF大扫荡计划正在稳步进行. [A]Olympiad 题意: 给\(n\)个人颁奖,要满足: 至少有一个人拿奖. 如果得分为\(x\)的有奖,那么 ...
- 【codeforces】【比赛题解】#869 CF Round #439 (Div.2)
良心赛,虽然我迟了半小时233333. 比赛链接:#869. 呃,CF的比赛都是有背景的……上次是<哈利波特>,这次是<物语>…… [A]巧妙的替换 题意: Karen发现了石 ...
随机推荐
- typora中文版官方免费快速下载以及Markdown的一些常用语法、Java知识点
typora下载 链接:https://某度云盘的域名/s/1geD1APxnyV3gogYW3E08bQ 密码:8fdp 把某度云盘的域名进行替换 1.标题 # 标题1 ## 标题2 ### 标题3 ...
- Java http请求工具类
该工具类可以调用POST请求或者Get请求,参数以Map的方式传入,支持获获取返回值,返回值接收类型为String HttpRequestUtil.java package com.util; imp ...
- Spring-data-redis redis
什么是spring-data-redis spring-data-redis是spring-data模块的一部分,专门用来支持在spring管理项目对redis的操作,使用java操作redis最常用 ...
- day15模块内容
1.生成器表达式 先说三元表达式如下 res = [i for i in range(10) if 1 > 5] 这样res就是一个列表6,7,8,9] 只要在这个基础上稍加调整,如下 方括号改 ...
- CentOS Find命令
find命令用来在指定目录下查找文件.任何位于参数之前的字符串都将被视为欲查找的目录名.如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件.并且将查找到的子目录和文件全部进 ...
- layui复选框
效果图 layui复选框,一个主的复选框控制多个从复选框,主复选框和从复选框的颜色不一样 layui复选框的样式,都是在选然后才会有的,所以直接通过css设置就实现不了了.只可以通过js动态设置 ht ...
- nodejs中.npmrc文件的内容
. nodejs安装后,使用npm安装模块的时候我出现了一个错误. getaddrinfo ENOTFOUND xxx 主要是这个配置文件的问题.搞不清楚.直接打开把文件内容删除变成 npmrc文件内 ...
- jsp页面之初体验
最近在学jsp 在web.xml页面中学到了如何让一个页面第一个启动
- java虚拟机的原理
所谓虚拟机,就是一台虚拟的机器.它是一款软件,用来执行一系列虚拟计算机指令,大体上虚拟机可以分为系统虚拟机和程序虚拟机,Visual Box .Vmare就属于系统虚拟机.他们完全是对物理计算机的仿真 ...
- 伪异步IO
针对传统的BIO编程,当客户端数量一直增加的情况下,可能会导致服务器直接奔溃掉,进而出现了一种伪异步IO的线程方式. 先看一下代码: 看一下server端的代码: 其中使用了自定义的一个线程池Hand ...