区间修改区间和:
#include<stdio.h>
#include<algorithm>
#define maxn 50005
using namespace std;
ll a[maxn << 2], lazy[maxn << 2], n;
void pushup(int k){ a[k] = a[k << 1] + a[k << 1 | 1]; }
void pushdown(int k, int m)
{
if (lazy[k]){
lazy[k << 1] += lazy[k];
lazy[k << 1 | 1] += lazy[k];
a[k << 1] += (m - (m >> 1)) * lazy[k];
a[k << 1 | 1] += (m >> 1) * lazy[k];
lazy[k] = 0;
}
}
void build(int k, int l, int r)
{
if (l == r){
scanf("%d", &a[k]);
return ;
}
int m = (l + r) >> 1;
build(k << 1, l, m);
build(k << 1 | 1, m + 1, r);
pushup(k);
}
void update(int k, int l, int r, int x, int y, int v)
{
if (x <= l && r <= y){
lazy[k] += v;
a[k] += v * (r - l + 1);
return ;
}
pushdown(k, r - l + 1);
int m = (l + r) >> 1;
if (x <= m) update(k << 1, l, m, x, y, v);
if (m < y) update(k << 1 | 1, m + 1, r, x, y, v);
pushup(k);
}
ll query(int k, int l, int r, int x, int y)
{
if(x <= l && r <= y) return a[k];
pushdown(k, r - l + 1);
ll res = 0, m = (l + r) >> 1;
if (x <= m) res += query(k << 1, l, m, x, y);
if (m < y) res += query(k << 1 | 1, m + 1, r, x, y);
return res;
}
单点修改区间最大值
#include<stdio.h>
#include<algorithm>
using namespace std;
#define maxn 200005
int n, m;
int a[maxn << 2], lazy[maxn << 2];
void pushup(int k){ a[k] = max(a[k << 1], a[k << 1 | 1]); }
void build(int k, int l, int r)
{
if (l == r){
scanf("%d", &a[k]);
return ;
}
int m = (l + r) >> 1;
build(k << 1, l, m);
build(k << 1 | 1, m + 1, r);
pushup(k);
}
void update(int k, int l, int r, int x, int v)
{
if (l == r){
a[k] = v;
return ;
}
int m = (l + r) >> 1;
if (x <= m) update(k << 1, l, m, x, v);
else update(k << 1 | 1, m + 1, r, x, v);
pushup(k);
}
int query(int k, int l, int r, int x, int y)
{
if (x <= l && r <= y) return a[k];
int m = (l + r) >> 1, res = 0;
if (x <= m) res = max(res, query(k << 1, l, m, x, y));
if (m < y) res = max(res, query(k << 1 | 1, m + 1, r, x, y));
return res;
}
POJ – 3667 – Hotel(线段树区间合并)
http://poj.org/problem?id=3667
#include<stdio.h>
#include<algorithm>
#define maxn 50005
using namespace std;
struct e{
int sum, ls, rs, tag;
}a[maxn << 2];
void pushup(int k, int d)
{
int l = k << 1, r = k << 1 | 1;
a[k].ls = a[l].ls, a[k].rs = a[r].rs;
if (a[k].ls == d - d / 2) a[k].ls += a[r].ls;
if (a[k].rs == d / 2) a[k].rs += a[l].rs;
a[k].sum = max(a[l].rs + a[r].ls, max(a[l].sum, a[r].sum));
return ;
}
void pushdown(int k, int d)
{
if (a[k].tag){
int l = k << 1, r = k << 1 | 1;
a[l].tag = a[r].tag = a[k].tag;
a[l].ls = a[l].rs = a[l].sum = a[k].tag > 0 ? 0 : d - d / 2;
a[r].ls = a[r].rs = a[r].sum = a[k].tag > 0 ? 0 : d / 2;
a[k].tag = 0;
}
return ;
}
void build(int k, int l, int r)
{
a[k].sum = a[k].ls = a[k].rs = r - l + 1;
if (l == r) return ;
int m = (l + r) >> 1;
build(k << 1, l, m);
build(k << 1 | 1, m + 1, r);
return ;
}
void update(int k, int l, int r, int x, int y, int c)
{
if (x <= l && r <= y){
a[k].ls = a[k].rs = a[k].sum = c > 0 ? 0 : r - l + 1;
a[k].tag = c;
return ;
}
pushdown(k, r - l + 1);
int m = (l + r) >> 1;
if (x <= m) update(k << 1, l, m, x, y, c);
if (m < y) update(k << 1 | 1, m + 1, r, x, y, c);
pushup(k, r - l + 1);
return ;
}
int query(int k, int l, int r, int d)
{
if (l == r) return 1;
pushdown(k, r - l + 1);
int m = (l + r) >> 1;
if (a[k << 1].sum >= d) return query(k << 1, l, m, d);
if (a[k << 1].rs + a[k << 1 | 1].ls >= d) return m - a[k << 1].rs + 1;
return query(k << 1 | 1, m + 1, r, d);
}
int main()
{
int n, m, p, x, d, pos;
scanf("%d %d", &n, &m);
build(1, 1, n);
while (m--){
scanf("%d", &p);
if (p == 1){
scanf("%d", &d);
if (d > a[1].sum){
puts("0");
continue;
}
pos = query(1, 1, n, d);
update(1, 1, n, pos, pos + d - 1, 1);
printf("%d\n", pos);
}else{
scanf("%d %d", &x, &d);
update(1, 1, n, x, x + d - 1, -1);
}
}
return 0;
}