B Stone Age Problem
点此进入题面
题意:
实现 区间赋值,区间查询
思路:
区间赋值,显然要用到懒标记,即编写 pushdown 函数
区间查询,编写 pushup 函数
具体细节见代码。结合 线段树懒标记的模板。
代码:
#define _CRT_SECURE_NO_WARNINGS 1
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef map<int, int> mi;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 2e5 + 10;
int a[N];
struct node
{
int l, r;
ll lazy;
ll sum;
} t[N << 2];
int n, q;
void pushup(int u)
{
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
}
void pushdown(int u)
{
auto& le = t[u << 1], & ri = t[u << 1 | 1], & rt = t[u];
if (rt.lazy)
{
le.lazy = ri.lazy = rt.lazy;
le.sum = (le.r - le.l + 1) * rt.lazy, ri.sum = (ri.r - ri.l + 1) * rt.lazy;
rt.lazy = 0;
}
}
void build(int u, int l, int r)
{
t[u] = { l, r, 0 };
if (l == r) { t[u].sum = a[l]; return; }
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int r, ll v)
{
if (t[u].l >= l && t[u].r <= r)
{
t[u].sum = (t[u].r - t[u].l + 1) * v;
t[u].lazy = v;
return;
}
pushdown(u);
int mid = t[u].l + t[u].r >> 1;
if (l <= mid) modify(u << 1, l, r, v);
if (r > mid) modify(u << 1 | 1, l, r, v);
pushup(u);
}
ll ask(int u, int l, int r)
{
if (l <= t[u].l && r >= t[u].r) return t[u].sum;
int mid = t[u].l + t[u].r >> 1;
ll res = 0;
if (l <= mid) res += ask(u << 1, l, r);
if (r > mid) res += ask(u << 1 | 1, l, r);
return res;
}
signed main()
{
int T = 1;
//cin>>T;
while (T--)
{
cin >> n >> q;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
build(1, 1, n);
while (q--)
{
int op; scanf("%d", &op);
if (op == 1)
{
int x; ll v; scanf("%d%lld", &x, &v);
modify(1, x, x, v);
}
else
{
ll v; scanf("%lld", &v);
modify(1, 1, n, v);
}
printf("%lld\n", ask(1, 1, n));
}
}
return 0;
}