Codeforces Round #727 div.2 A-F题解
Posted 欣君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #727 div.2 A-F题解相关的知识,希望对你有一定的参考价值。
视频讲解:BV15M4y1g7cf
A. Contest Start
题目大意
有
n
n
n 名选手参加比赛,第
i
i
i 名选手的比赛在
(
i
−
1
)
∗
x
(i-1)*x
(i−1)∗x 时刻开始,持续
t
t
t 分钟后结束。
每名选手的不满意度,等于其结束比赛时,其他开始了(或恰好开始)比赛但尚未结束的选手数量。
求所有选手的不满意度总和。
1
≤
n
,
x
,
t
≤
2
⋅
1
0
9
1 \\leq n,x,t \\leq 2 \\cdot 10^9
1≤n,x,t≤2⋅109
题解
若
t
<
x
t < x
t<x ,则每名选手的比赛时间不会重叠,不满意度为
0
0
0 。
当选手足够多时,除了最后若干名选手,其余选手的不满意度等于
t
/
x
t/x
t/x 。最后若干名选手的不满意度是从
t
/
x
−
1
t/x-1
t/x−1 到
0
0
0 的公差为-1的等差数列。
当选手不够多时,则第一名选手结束比赛时,其他选手都已经开始比赛了。因此不满意度是从
n
−
1
n-1
n−1 到
0
0
0 的公差为
−
1
-1
−1 的等差数列。
选手数量多少的分界线为
t
/
x
t/x
t/x 。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int main()
int T;
ll n,x,t,ans;
scanf("%d",&T);
while(T--)
scanf("%lld%lld%lld",&n,&x,&t);
if(t<x)
printf("0\\n");
else
if(t/x<=n-1)
ans=t/x*n-(1+t/x)*(t/x)/2;
else
ans=(n-1+0)*n/2;
printf("%lld\\n",ans);
B. Love Song
题目大意
给定长度为
n
(
1
≤
n
≤
1
0
5
)
n(1 \\leq n \\leq 10^5)
n(1≤n≤105) 的字符串
s
s
s,有
q
(
1
≤
q
≤
1
0
5
)
q(1 \\leq q \\leq 10^5)
q(1≤q≤105) 次询问,每次询问指定其中的一个连续子串
s
[
l
,
r
]
s[l,r]
s[l,r],将,求将其中的字母重复若干次后的长度。
‘a’ 重复1次, ‘b’ 重复2次,。。。, ‘z’ 重复26次。
题解
用前缀和处理即可。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN=100100;
char s[MAXN];
int sum[MAXN];
int main()
int n,q,i,j,l,r,ans;
scanf("%d%d",&n,&q);
scanf("%s",s+1);
for(i=1;i<=n;i++)
sum[i]=sum[i-1]+(s[i]-'a'+1);
while(q--)
scanf("%d%d",&l,&r);
printf("%d\\n",sum[r]-sum[l-1]);
C. Stable Groups
题目大意
给定
n
(
1
≤
n
≤
2
⋅
1
0
5
)
n(1 \\leq n \\leq 2 \\cdot 10^5)
n(1≤n≤2⋅105) 名学生,每名学生有水平
a
i
(
1
≤
a
i
≤
1
0
18
)
a_i(1 \\leq a_i \\leq 10^18)
ai(1≤ai≤1018) ,将其分为若干个稳定组,允许增加任意水平的
k
(
0
≤
k
≤
1
0
18
)
k(0 \\leq k \\leq 10^18)
k(0≤k≤1018) 名学生。求最少的稳定组数量。
稳定组定义:将组内学生按水平排序后,相邻两位学生的水平差不超过
x
(
1
≤
x
≤
1
0
18
)
x(1 \\leq x \\leq 10 ^18)
x(1≤x≤1018) 。
题解
先对所有学生按水平排序,计算不添加额外学生的情况下的稳定组数量,并记录相邻组间,至少要添加多少名学生,才能使得这两组合并在一起。
对相邻组间合并所需的学生数量排序,从小到大贪心填补学生即可。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN=200200;
ll a[MAXN],dif[MAXN];
int main()
int n,i,ans,cnt;
ll k,x,ad;
scanf("%d%lld%lld",&n,&k,&x);
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
sort(a+1,a+n+1);
cnt=0;
ans=1;
for(i=2;i<=n;i++)
if(a[i]-a[i-1]>x)
ans++;
dif[cnt++]=a[i]-a[i-1];
sort(dif,dif+cnt);
for(i=0;i<cnt;i++)
ad=(dif[i]-1)/x;
if(ad<=k)
ans--;
k-=ad;
printf("%d\\n",ans);
D. PriceFixed
题目大意
有
n
(
1
≤
n
≤
1
0
5
)
n(1 \\leq n \\leq 10^5)
n(1≤n≤105) 种商品要买,每种商品初始价格
2
2
2 元,第
i
i
i 种商品至少要买
a
i
(
1
≤
a
i
≤
1
0
1
4
)
a_i(1 \\leq a_i \\leq 10^14)
ai(1≤ai≤1014) 个。
如果之前已经买了
b
i
(
1
≤
b
i
≤
1
0
1
4
)
b_i(1 \\leq b_i \\leq 10^14)
bi(1≤bi≤1014) 件商品,那么之后买第
i
i
i 件商品半价。
可以任意调整购买顺序,求最小花费。
题解
将所有商品按
b
i
b_i
bi 排序,贪心考虑如何购买。
如果有打折的,则优先购买打折商品直到该商品买够
a
i
a_i
ai 个。
如果没有打折的,则购买尚未买够的
b
i
b_i
bi 最高的商品,直到有商品能够打折,或
b
i
b_i
bi 最高的商品买够
a
i
a_i
ai 件。
实现时,用双指针头尾维护可能打折的
b
i
b_i
bi 最低的商品和尚未买够的
b
i
b_i
bi 最高的商品。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN=100100;
struct Product
ll a,b;
int id;
p[MAXN];
bool cmp(Product p1,Product p2)
return p1.b<p2.b;
int main()
int n,i,l,r;
ll ans,sum,num;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%lld%lld",&p[i].a,&p[i].b);
p[i].id=i;
sort(p+1,p+n+1,cmp);
l=1,r=n;
sum=0,ans=0;
while(l<=r)
if(p[l].b<=sum)
sum+=p[l].a;
ans+=p[l].a;
l++;
else
num=min(p[r].a,p[l].b-sum);
sum+=num;
ans+=2*num;
p[r].a-=num;
if(p[r].a==0)
r--;
printf("%lld\\n",ans);
E. Game with Cards
题目大意
初始左右手上各有一张数字为 0 0 0 的卡牌。有 n n n 次操作,每次操作有一张新的数字为 k i k_i kCodeforces Round #727 div.2 A-F题解
Codeforces Round #727 (Div. 2) F. Strange Array(思维,线段树子段和)
Codeforces Round #727 (Div. 2) E. Game with Cards(巧妙dp的优化)
Codeforces Round #727 (Div. 2) E. Game with Cards(dp优化,从n^2到nlog到n)