C. Tea Tasting

题目

链接:https://codeforces.com/problemset/problem/1795/C or https://www.luogu.com.cn/problem/CF1795C
总思路:
利用数组记录a[N], b[N]分别记录每杯茶的量,每个人喝的量,然后每个人喝的量进行前缀和,再二分查找,利用divx和mod来确定每个人喝的量:divx是喝了几整杯;mod是额外的小量。
代码:
其中divx采用差分数组的方式(因为有区间修改)

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const ll N = 2e5 + 10;
ll a[N], b[N];
ll mod[N], divx[N];
int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	ll t; cin >> t;
	while (t--)
	{
		ll n; cin >> n;
		for (int i = 1; i <= n; i++)cin >> a[i];
		for (int i = 1; i <= n; i++) { cin >> b[i]; b[i] += b[i - 1]; }
		memset(mod, 0, sizeof(mod)); memset(divx, 0, sizeof(divx));
		//divx:差分,mod:多余的
		for (int i = 1; i <= n; i++)
		{
			//第i杯茶最多供应到k号人
			ll l = i, r = n;
			while (l < r)
			{
				ll mid = l + (r - l + 1) / 2;
				if (b[mid] - b[i - 1] <= a[i])l = mid;
				else r = mid-1;
			}
			if (b[l] - b[i - 1] < a[i])
			{
				mod[l + 1] += a[i] - (b[l] - b[i - 1]);
			}
			if (a[i] >= b[i] - b[i - 1])
				divx[i]++, divx[l + 1]--;
			else mod[i] += a[i];//如果第i杯水连第i号人都不能满足
			
		}
		ll suma = 0;
		for (int i = 1; i <= n; i++)
		{
			suma += divx[i];//差分
			cout << suma * (b[i] - b[i - 1]) + mod[i] << ' ';//总数
		}
		cout << '\n';
	}

	return 0;
}
posted @ 2024-05-31 16:51  WHUStar  阅读(22)  评论(0)    收藏  举报