luogu P2221 [HAOI2012]高速公路

这种思博题有什么好写的呀

直接考虑每条边的贡献,然后把贡献的式子拆开,再维护一下就好了
你们随便看看吧
在这里插入图片描述
思博题
线段树维护3个值就好了QWQ
code:

#include<bits/stdc++.h>
#define N 200005
#define int long long
using namespace std;
int gcd(int x, int y) {
	return y? gcd(y, x % y) : x;
}
struct A {
	int s, s1, s2, tag;
}a[N << 4];
int sum1[N], sum2[N];
void update(int rt) {
	a[rt].s = a[rt << 1].s + a[rt << 1 | 1].s;
	a[rt].s1 = a[rt << 1].s1 + a[rt << 1 | 1].s1;
	a[rt].s2 = a[rt << 1].s2 + a[rt << 1 | 1].s2;
}
void pushdown(int rt, int l, int r) {
	if(a[rt].tag) {
		int mid = (l + r) >> 1;
		a[rt << 1].tag += a[rt].tag;
		a[rt << 1 | 1].tag += a[rt].tag;
		a[rt << 1].s += (mid - l + 1) * a[rt].tag;
		a[rt << 1 | 1].s += (r - mid) * a[rt].tag;
		a[rt << 1].s1 += (sum1[mid] - sum1[l - 1]) * a[rt].tag;
		a[rt << 1 | 1].s1 += (sum1[r] - sum1[mid]) * a[rt].tag;
		a[rt << 1].s2 += (sum2[mid] - sum2[l - 1]) * a[rt].tag;
		a[rt << 1 | 1].s2 += (sum2[r] - sum2[mid]) * a[rt].tag;
		a[rt].tag = 0;
	}
}
void add(int rt, int l, int r, int L, int R, int o) {
	pushdown(rt, l, r);
	if(L <= l && r <= R) {
		a[rt].tag += o;
		a[rt].s += (r - l + 1) * o;
		a[rt].s1 += (sum1[r] - sum1[l - 1]) * o;
		a[rt].s2 += (sum2[r] - sum2[l - 1]) * o;
		return;
	}
	int mid = (l + r) >> 1;
	if(L <= mid) add(rt << 1, l, mid, L, R, o);
	if(R > mid) add(rt << 1 | 1, mid + 1, r, L, R, o);
	update(rt);
}
A query(int rt, int l, int r, int L, int R) {
	pushdown(rt, l, r);
	if(L <= l && r <= R) return a[rt];
	int mid = (l + r) >> 1;
	A ret = {0, 0, 0, 0};
	if(L <= mid) ret = query(rt << 1, l, mid, L, R);
	if(R > mid) {
		A rett = query(rt << 1 | 1, mid + 1, r, L, R);
		ret.s += rett.s, ret.s1 += rett.s1, ret.s2 += rett.s2;
	}
	return ret;
}
int n, m;
signed main() {
	scanf("%lld%lld", &n, &m); n --;
	for(int i = 1; i <= n; i ++) sum1[i] = sum1[i - 1] + i, sum2[i] = sum2[i - 1] + i * i;
	while(m --) {
		char c;
		int l, r, x;
		scanf(" %c", &c);
		if(c == 'C') {
			scanf("%lld%lld%lld", &l, &r, &x); r --;
			add(1, 1, n, l, r, x);
		} else {
			scanf("%lld%lld", &l, &r); r --;
			A ha = query(1, 1, n, l, r);
			int fz = -(l*r+l-r-1)*ha.s + (r+l)*ha.s1 - ha.s2;
			int fm = (r - l + 2) * (r - l + 1) / 2;
			int d = gcd(fz, fm);
			fz /= d, fm /= d;
			printf("%lld/%lld\n", fz, fm);	
		}		
	}
	return 0;
}

坑点

long long

发布了157 篇原创文章 · 获赞 90 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_38944163/article/details/103502586