Codeforces Round #727 div.2 A-F题解

Posted 欣君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #727 div.2 A-F题解相关的知识,希望对你有一定的参考价值。

视频讲解:TBD

A. Contest Start

题目大意

n n n 名选手参加比赛,第 i i i 名选手的比赛在 ( i − 1 ) ∗ x (i-1)*x (i1)x 时刻开始,持续 t t t 分钟后结束。
每名选手的不满意度,等于其结束比赛时,其他开始了(或恰好开始)比赛但尚未结束的选手数量。
求所有选手的不满意度总和。
1 ≤ n , x , t ≤ 2 ⋅ 1 0 9 1 \\leq n,x,t \\leq 2 \\cdot 10^9 1n,x,t2109

题解

t < x t < x t<x ,则每名选手的比赛时间不会重叠,不满意度为 0 0 0
当选手足够多时,除了最后若干名选手,其余选手的不满意度等于 t / x t/x t/x 。最后若干名选手的不满意度是从 t / x − 1 t/x-1 t/x1 0 0 0 的公差为-1的等差数列。
当选手不够多时,则第一名选手结束比赛时,其他选手都已经开始比赛了。因此不满意度是从 n − 1 n-1 n1 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(1n105) 的字符串 s s s,有 q ( 1 ≤ q ≤ 1 0 5 ) q(1 \\leq q \\leq 10^5) q(1q105) 次询问,每次询问指定其中的一个连续子串 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(1n2105) 名学生,每名学生有水平 a i ( 1 ≤ a i ≤ 1 0 18 ) a_i(1 \\leq a_i \\leq 10^{18}) ai(1ai1018) ,将其分为若干个稳定组,允许增加任意水平的 k ( 0 ≤ k ≤ 1 0 18 ) k(0 \\leq k \\leq 10^{18}) k(0k1018) 名学生。求最少的稳定组数量。
稳定组定义:将组内学生按水平排序后,相邻两位学生的水平差不超过 x ( 1 ≤ x ≤ 1 0 18 ) x(1 \\leq x \\leq 10 ^{18}) x(1x1018)

题解

先对所有学生按水平排序,计算不添加额外学生的情况下的稳定组数量,并记录相邻组间,至少要添加多少名学生,才能使得这两组合并在一起。
对相邻组间合并所需的学生数量排序,从小到大贪心填补学生即可。

参考代码

#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(1n105) 种商品要买,每种商品初始价格 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(1ai1014) 个。
如果之前已经买了 b i ( 1 ≤ b i ≤ 1 0 1 4 ) b_i(1 \\leq b_i \\leq 10^14) bi(1bi1014) 件商品,那么之后买第 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 Codeforces 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)

Codeforces Round #705 (Div. 2)

Codeforces Round #774 (Div. 2)