Educational Codeforces Round 177 (Rated for Div. 2) ab题解

A. Cloudberry Jam

题目大意是说 akg的浆果和akg糖混在一起可以配出(2*a*(3/4))kg的果酱(因为蒸发掉了1/4)

而一罐果酱要3kg。给出果酱罐数n,让你求出a的值。也就是(n*3)/(2*(3/4)),化简为n*2。

#include<bits/stdc++.h> 
using namespace std;
int main(){
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		cout<<n*2<<endl;
	}
	return 0;
} 

B. Large Array and Segments

题目大意是说 给一个数组a,数组b由k个循环重复的数组a组成。

给出一个x,计算数组b中满足存在r>=l使得区间[l,r]元素和至少为x的l的数量。

令r=a[n](这样对于每个l,[l,r]区间元素和最大),从后往前一一排除元素和小于x的l;

以(a={3,4,1,2,5},k=3,x=10)为例,如图:

而从第一个满足的l开始往前的每一个元素都将满足条件。(因为递增)

考虑后缀和+二分查找

#include<bits/stdc++.h>

using namespace std;
using ll=long long;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int t;cin>>t;
	while(t--){
		int n,k;ll x;
		cin>>n>>k>>x;
		int a[n+1];ll b[n+2];
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		b[n+1]=0;
		for(int i=n;i>=1;i--) b[i]=b[i+1]+a[i];
		//后缀和 
		ll s=b[1];
		//每一个数组a的总和为s 
		if(k*s<x){
			cout<<0<<endl;continue;
		}//总和小于x直接跳过 
		ll ans=0;int i;
		for(i=0;i<k;i++){
			int l=1,r=n;
			int res=-1; 
			while(l<=r){
				int mid=l+(r-l)/2;
				if((b[mid]+i*s)<x) r=mid-1;
				else{
					res=mid;
					l=mid+1;
				}
			}//二分找第一个满足的l,注意取边界 
			if(res!=-1){
				ans+=res;
				ans+=(ll)(k-1-i)*n;
				break;
			}//第一发wa是因为没开ll,警钟敲烂 
		}
		cout<<ans<<endl;
	} 
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值