您的位置:首页 > 其它

hihocoder1078线段树修改区间查询区间(懒标记)

2015-02-22 12:53 417 查看
题目链接:http://hihocoder.com/problemset/problem/1078

我的代码:

#include <iostream>
#include <algorithm>

using namespace std;

#define MAXN 100005

int w[MAXN];

struct segNode
{
int left, right, sum;
bool lazy;
};

struct segTree
{
segNode t[4*MAXN];
void build(int i, int l, int r)
{
t[i].left = l;
t[i].right = r;
t[i].lazy = false;
if(l<r)
{
int m = (l+r)/2;
build(2*i, l, m);
build(2*i+1, m+1, r);
t[i].sum = t[2*i].sum+t[2*i+1].sum;
}
else t[i].sum = w[l];
}
int query(int i, int l, int r)
{
if(t[i].lazy) pushdown(i);
if(t[i].left==l&&t[i].right==r) return t[i].sum;
int m = (t[i].left+t[i].right)/2;
if(l>m) return query(2*i+1, l, r);
if(r<=m) return query(2*i, l, r);
return query(2*i, l, m)+query(2*i+1, m+1, r);
}
void update(int i, int l, int r, int v)
{
if(t[i].lazy) pushdown(i);
if(t[i].left==l&&t[i].right==r)
{
t[i].sum = (t[i].right-t[i].left+1)*v;
t[i].lazy = true;
}
else
{
int m = (t[i].left+t[i].right)/2;
if(l>m) update(2*i+1, l, r, v);
else if(r<=m) update(2*i, l, r, v);
else
{
update(2*i, l, m, v);
update(2*i+1, m+1, r, v);
}
t[i].sum = t[2*i].sum+t[2*i+1].sum;
}
}
void pushdown(int i)
{
t[i].lazy = false;
if(t[i].left<t[i].right)
{
int l = t[i].right-t[i].left+1;
int ll = t[2*i].right-t[2*i].left+1;
int rl = t[2*i+1].right-t[2*i+1].left+1;
t[2*i].sum = t[i].sum/l*ll;
t[2*i+1].sum = t[i].sum/l*rl;
t[2*i].lazy = true;
t[2*i+1].lazy = true;
}
}
}tree;

int main()
{
int n, q;
bool op;
while(cin>>n)
{
for(int i=1; i<=n; ++i) cin>>w[i];
tree.build(1, 1, n);
cin>>q;
while(q--)
{
cin>>op;
if(op)
{
int l, r, v;
cin>>l>>r>>v;
tree.update(1, l, r, v);
}
else
{
int l, r;
cin>>l>>r;
cout<<tree.query(1, l, r)<<endl;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: