【模板】线段树维护区间和、最大最小值
俺回归复建辣!!!
这两天还是挺绝望的,曾经随手能打的线段树调了两天硬是卡不过洛谷,于是只好换了种方法写。
很多东西都记不得了,但幸好大一不上专业课可以慢慢捡回来一点。
没有人陪着一起打代码真的好孤单....真的想你们了。
了解到大家天南地北但是很多都进入了计算机软件信息之类的专业,说不定以后还可以多交流呢!大家要加油呀,在acm赛场再见!(也许呢)
回归第一章,献给线段树。
P3372 【模板】线段树 1
#include<bits/stdc++.h> #define ll long long using namespace std; ll ini[400005]; ll n, m; struct node { ll sum, mn, mx, laz; } tr[400005]; ll lc(ll pos) { return (pos << 1); } ll rc(ll pos) { return ((pos << 1) + 1);} void update(ll pos) { tr[pos].sum = tr[lc(pos)].sum + tr[rc(pos)].sum; tr[pos].mn = min(tr[lc(pos)].mn, tr[rc(pos)].mn); tr[pos].mx = max(tr[lc(pos)].mx, tr[rc(pos)].mx); } void build(ll l ,ll r, ll pos) { if(l == r) { tr[pos].sum = ini[l]; tr[pos].mn = ini[l]; tr[pos].mx = ini[l]; return ; } ll mid = (l + r) >> 1; build(l, mid, pos << 1); build(mid + 1, r, (pos << 1) + 1); update(pos); } void pushdown(ll pos, ll l, ll r) { if(tr[pos].laz) { ll mid = (l + r) >> 1; tr[lc(pos)].laz += tr[pos].laz; tr[rc(pos)].laz += tr[pos].laz; tr[lc(pos)].sum += tr[pos].laz * (mid - l + 1); tr[rc(pos)].sum += tr[pos].laz * (r - mid); tr[lc(pos)].mn += tr[pos].laz; tr[lc(pos)].mx += tr[pos].laz; tr[rc(pos)].mn += tr[pos].laz; tr[rc(pos)].mx += tr[pos].laz; tr[pos].laz = 0; } } void add(ll pos, ll l, ll r, ll L, ll R, ll d) { if(L >= l && R <= r) { tr[pos].sum += d * (R - L + 1); tr[pos].laz += d; tr[pos].mn += d; tr[pos].mx += d; return ; } pushdown(pos, L, R); ll mid = (L + R) >> 1; if(mid >= l) add(lc(pos), l, r, L, mid, d); if(mid < r) add(rc(pos), l, r, mid + 1, R, d); update(pos); } node query(ll pos, ll l, ll r, ll L, ll R) { if(L >= l && R <= r) return tr[pos]; pushdown(pos, L, R); ll mid = (L + R) >> 1; node ans; ans.sum=0,ans.mn=0x7fffffff,ans.mx=-100000000; if(mid >= l) { node jq = query(pos << 1, l, r, L, mid); ans.mn = min(ans.mn, jq.mn); ans.sum += jq.sum; ans.mx = max(ans.mx, jq.mx); } if(mid < r) { node jq = query((pos << 1) + 1, l, r, mid + 1, R); ans.mn = min(ans.mn, jq.mn ); ans.sum += jq.sum; ans.mx = max(ans.mx, jq.mx); } return ans; } int main() { scanf("%lld%lld", &n, &m); for(int i = 1; i <= n; i ++) scanf("%lld", &ini[i]); build(1, n, 1); for(int i = 1; i <= m; i ++) { ll x, y, z, s; scanf("%lld", &s); if(s == 1) { scanf("%lld%lld%lld", &x, &y, &z); add(1, x, y, 1, n, z); } if(s == 2) { scanf("%lld%lld", &x, &y); node ans = query(1, x, y, 1, n); printf("%lld\n", ans.sum); } } return 0; }
还是我的代码风格!(丑),复制了以前提交记录的main部分终于a掉了。
感谢洛谷有提交记录,感谢我以前写的blog,让u盘坏掉又丢失后一切还有迹可循。
下午去找$Abyssful$一起打代码辣。开心。