璟雯院

珺璟如晔,雯华若锦

用户工具

站点工具


icpc:problems:usaco23open_milk_sum_s
problems
名称Milk Sum S
题目编号USACO23OPEN_S1
题目链接luogu.com.cn/…
来源USACO
算法分类二分, 数学, 前缀和
难易程度容易

Milk Sum S

想法

单次修改会对一段区间的数造成影响,故使用二分查找每次修改后的位置,再将整段区间统一进行调整。

代码实现

#include<cstdio>
#include<algorithm>
 
const int N = 1.5 * 1e5 + 10;
struct node{
	int sit, val;
	friend bool operator<(const node a, const node b) {
		return a.val < b.val;
	}
};
node line[N];
int pos[N], a[N];
long long int sum[N];
 
int main() {
	int n, T, x, y;
	long long int all = 0;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
		line[i] = (node){ i, a[i] };
	}
	std::sort(line+1, line+1+n);
	for (int i = 1; i <= n; ++i) {
		pos[line[i].sit] = i;
		sum[i] = sum[i-1] + line[i].val;
		all += 1LL * line[i].val * i;
	}
	scanf("%d", &T);
	while(T--) {
		long long int temp = all;
		scanf("%d %d", &x, &y);
		if(a[x] < y) {
			int l = pos[x]+1, r = n, mid;
			while(l < r) {
				mid = (l + r + 1) / 2;
				if(line[mid].val <= y)
					l = mid;
				else
					r = mid - 1;
			}
			if(line[l].val > y)
				l--;
			temp = temp - 1LL*a[x]*pos[x] - (sum[l]-sum[pos[x]]) + 1LL*y*l;
		}
		else if(a[x] > y) {
			int l = 1, r = pos[x]-1, mid;
			while(l < r) {
				mid = (l + r + 1) / 2;
				if(line[mid].val <= y)
					l = mid;
				else
					r = mid - 1;
			}
			if(line[l].val > y) 
				l--;
			temp = temp - 1LL*a[x]*pos[x] + (sum[pos[x]-1]-sum[l]) + 1LL*y*(l+1);
		}
		printf("%lld\n", temp);
	}
	return 0;
}
/app/www/public/data/pages/icpc/problems/usaco23open_milk_sum_s.txt · 最后更改: 2023/05/24 06:49 由 温婕莺