您的位置:首页 > 其它

[模板]线段树

2016-04-15 15:12 302 查看
codevs 1080–1082

区间求和 && 区间修改

代码如下√

(线段树练习3)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define L(x) (x << 1)       //左儿子
#define R(x) (x << 1 | 1)   //右儿子
#define sz(x) (tree[x].r - tree[x].l + 1)   //区间长度
const int MAXN = 200000 + 5;
using namespace std;
long long n,a,b,x,q,z,t,y;
long long num[200000 + 5];
struct doc
{
long long l,r;      //左,右
long long sum,add;  //和,加
}tree[MAXN << 2];

void update(long long p)//标记清空
{
tree[p].sum = tree[L(p)].sum + tree[R(p)].sum;
return;
}

void spread(long long p)//标记下放
{
if(!tree[p].add)
return;
tree[L(p)].add += tree[p].add;
tree[R(p)].add += tree[p].add;
tree[L(p)].sum += tree[p].add * sz(L(p));
tree[R(p)].sum += tree[p].add * sz(R(p));
tree[p].add = 0;
update(p);
return;
}

void build(long long l,long long r,long long p)
{
tree[p].l = l;
tree[p].r = r;
if(l == r)//如果相等则无儿子
{
tree[p].sum = num[l];
return;
}
long long mid = (tree[p].l + tree[p].r) >> 1;
build(l,mid,L(p));
build(mid + 1,r,R(p));
update(p);
return;
}

void change(long long l,long long r,long long p,long long v)//修改
{
if(l <= tree[p].l && tree[p].r <= r)
{
tree[p].add += v;
tree[p].sum += v * sz(p);
return;
}
spread(p);
long long mid = (tree[p].l + tree[p].r) >> 1;
if(l <= mid)
change(l,r,L(p),v);
if(mid < r)
change(l,r,R(p),v);
update(p);
return;
}

long long ask(long long l,long long r,long long p)//查询
{
if(l <= tree[p].l && tree[p].r <= r)
return tree[p].sum;
spread(p);
long long mid = (tree[p].l + tree[p].r) >> 1;
long long ans = 0;
if(l <= mid)
ans += ask(l,r,L(p));
if(mid < r)
ans += ask(l,r,R(p));
update(p);
return ans;
}

int main()
{
memset(num,0,sizeof(num));
scanf("%lld",&n);
for(long long i = 1; i <= n; i ++)
scanf("%lld",&num[i]);
build(1,n,1);
scanf("%lld",&q);
for(long long i = 1; i <= q; i ++)
{
scanf("%lld",&t);
if(t == 1)
{
scanf("%lld %lld %lld",&a,&b,&x);
change(a,b,1,x);
}
else if(t == 2)
{
scanf("%lld %lld",&y,&z);
printf("%lld\n",ask(y,z,1));
}
}
return 0;
}


以上√
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: