4878. 维护数组(线段树维护区间和)

题目如下:

4878. 维护数组(线段树维护区间和)_第1张图片

输入样例1:

5 2 2 1 8
1 1 2
1 5 3
1 2 1
2 2
1 4 2
1 3 2
2 1
2 3

输出样例1:

3
6
4

输入样例2:

5 4 10 1 6
1 1 5
1 5 5
1 3 2
1 5 2
2 1
2 2

输出样例2:

7
1

题目链接

题解 or 思路:

线段树维护两种区间和

  1. 区间 ∑ m i n ( d i , a ) \sum min(d_i, a) min(di,a)
  2. 区间 ∑ m i n ( d i , b ) \sum min(d_i, b) min(di,b)

AC 代码如下:

/*
Make it simple and keep self stupid
author:Joanh_Lan
*/
#pragma GCC optimize(3)
#pragma GCC optimize("inline") // 如果比赛允许开编译器优化的话,可以默写这两段
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define buff                     \
    ios::sync_with_stdio(false); \
    cin.tie(0);
// #define int long long
#define ll long long
#define PII pair<int, int>
#define px first
#define py second
typedef std::mt19937 Random_mt19937;
Random_mt19937 rnd(time(0));
using namespace std;
const int mod = 1e9 + 7;
const int inf = 2147483647;
const int N = 200009;
//int Mod(int a,int mod){return (a%mod+mod)%mod;}
//int lowbit(int x){return x&-x;}//最低位1及其后面的0构成的数值
//int qmi(int a, int k, int p){int res = 1 % p;while (k){if (k & 1) res = Mod(res * a , p);a = Mod(a * a , p);k >>= 1;}return res;}
//int inv(int a,int mod){return qmi(a,mod-2,mod);}
//int lcm(int a,int b){return a*b/__gcd(a,b);}
int n, k, a, b, q;
struct Tree
{
	int v;
	int Sa, Sb;
}tr[N << 2];
void pushup(int x)
{
	tr[x].Sa = tr[x << 1].Sa + tr[x << 1 | 1].Sa;
	tr[x].Sb = tr[x << 1].Sb + tr[x << 1 | 1].Sb;
}
void update(int x, int s, int t, int val, int p)
{
	if (x == s && x == t)
	{
		tr[p].v += val;
		tr[p].Sa = min(a, tr[p].v);
		tr[p].Sb = min(b, tr[p].v);
		return;
	}
	int mid = s + ((t - s) >> 1);
	if (x <= mid)
		update(x, s, mid, val, p << 1);
	else if (x > mid)
		update(x, mid + 1, t, val, p << 1 | 1);
	pushup(p);
}
int Get_Sum(int l, int r, int s, int t, int p, int op)
{
	if (l > r)
		return 0;
	if (s >= l && t <= r)
	{
		if (op == 1)
			return tr[p].Sa;
		else 
			return tr[p].Sb;
	}
	int sum = 0;
	int mid = s + ((t - s) >> 1);
	if (l <= mid)
		sum += Get_Sum(l, r, s, mid, p << 1, op);
	if (r > mid)
		sum += Get_Sum(l, r, mid + 1, t, p << 1 | 1, op);
	return sum;
}
void solve()
{
	cin >> n >> k >> a >> b >> q;
	while (q--)
	{
		int op;	cin >> op;
		if (op == 1)
		{
			int x, y;	cin >> x >> y;
			update(x, 1, n, y, 1);
		}
		else
		{
			int p;	cin >> p;
			cout << Get_Sum(1, p - 1, 1, n, 1, 2) + Get_Sum(p + k, n, 1, n, 1, 1) << '\n';
		}
	}
}
int main()
{
	buff;
	int _ = 1;
	// cin >> _;
	while (_--)
		solve();
}

你可能感兴趣的:(数据结构,练习,c++,算法,数据结构,线段树)