CODEVS 1080 线段树练习 http://codevs.cn/problem/1080/
单点修改 区间查询
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f;
const int maxn = 1e5+5;
using namespace std;
struct node
{
int l,r,w;
}tree[4*maxn];
int n,m;
int q,x,y;
int ans ;
void build(int l ,int r ,int k)
{
tree[k].l = l; tree[k].r = r;
if(l==r) {cin >> tree[k].w; return ;}
int m = (l+r)/2;
build(l,m,k*2);
build(m+1,r,k*2+1);
tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
void sum(int k)
{
if(tree[k].l >=x && tree[k].r<=y)
{
ans+= tree[k].w;
return ;
}
int m = (tree[k].l+tree[k].r)/2;
if(x<=m) sum(k*2);
if(y>m) sum(k*2+1);
}
void add(int k )
{
if(tree[k].l == tree[k].r)
{
tree[k].w += y;
return ;
}
int m = (tree[k].l+tree[k].r)/2;
if(x<=m) add(k*2);
else add(k*2+1);
tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
int main()
{
ios::sync_with_stdio(false);
cin >>n;
build(1,n,1);
cin >> m;
for(int i=1;i<=m;i++)
{
cin >> q >> x >> y;
ans = 0;
if(q==1) add(1);
else
{
sum(1);
cout << ans << endl;
}
}
}
CODEVS 1081 线段树练习 2 http://codevs.cn/problem/1081/
区间修改 单点查询 (懒标记)
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f;
const int maxn = 1e5+5;
using namespace std;
struct node
{
int l,r,w,f;
}tree[4*maxn];
int n,m;
int q,x,y;
int ans ;
int a,b;
void build(int l ,int r ,int k)
{
tree[k].l = l; tree[k].r = r;
if(l==r) {cin >> tree[k].w; return ;}
int m = (l+r)/2;
build(l,m,k*2);
build(m+1,r,k*2+1);
tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
void sum(int k)
{
if(tree[k].l >=x && tree[k].r<=y)
{
ans+= tree[k].w;
return ;
}
int m = (tree[k].l+tree[k].r)/2;
if(x<=m) sum(k*2);
if(y>m) sum(k*2+1);
}
void down(int k) //下传标记
{
tree[k*2].f+=tree[k].f;
tree[k*2+1].f+=tree[k].f;
tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
tree[k].f = 0;
}
void add(int k )
{
if(tree[k].l>=a && tree[k].r<=b)
{
tree[k].w += x *(tree[k].r -tree[k].l+1);
tree[k].f += x;
return ;
}
if(tree[k].f) down(k);
int m = (tree[k].l+tree[k].r)/2;
if(a<=m) add(k*2);
if(b>m) add(k*2+1);
tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
void ask(int k)//单点查询
{
if(tree[k].l==tree[k].r)
{
ans=tree[k].w;
return ;
}
if(tree[k].f) down(k);//懒标记下传,唯一需要更改的地方
int m=(tree[k].l+tree[k].r)/2;
if(x<=m) ask(k*2);
else ask(k*2+1);
}
int main()
{
ios::sync_with_stdio(false);
cin >>n;
build(1,n,1);
cin >> m;
for(int i=1;i<=m;i++)
{
cin >> q ;
ans = 0;
if(q==1)
{
cin >> a >> b >> x;
add(1);
}
else
{
cin >> x;
ask(1);
cout << ans << endl;
}
}
}
CODEVS 1081 线段树练习 3 http://codevs.cn/problem/1082/
区间更新 区间查询(懒标记)
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f;
#define ll long long
const int maxn = 2e5+5;
using namespace std;
struct node
{
ll l,r,w,f;
}tree[4*maxn];
int n,m;
int q,x,y;
ll ans ;
int a,b;
void build(int l ,int r ,int k)
{
tree[k].l = l; tree[k].r = r;
if(l==r) {cin >> tree[k].w; return ;}
int m = (l+r)/2;
build(l,m,k*2);
build(m+1,r,k*2+1);
tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
void down(int k) //下传标记
{
tree[k*2].f+=tree[k].f;
tree[k*2+1].f+=tree[k].f;
tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
tree[k].f = 0;
}
void sum(int k)
{
if(tree[k].l >=a && tree[k].r<=b)
{
ans+= tree[k].w;
return ;
}
if(tree[k].f) down(k);
int m = (tree[k].l+tree[k].r)/2;
if(a<=m) sum(k*2);
if(b>m) sum(k*2+1);
}
void add(int k )
{
if(tree[k].l>=a && tree[k].r<=b)
{
tree[k].w += x *(tree[k].r -tree[k].l+1);
tree[k].f += x;
return ;
}
if(tree[k].f) down(k);
int m = (tree[k].l+tree[k].r)/2;
if(a<=m) add(k*2);
if(b>m) add(k*2+1);
tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
/*void ask(int k)//单点查询
{
if(tree[k].l==tree[k].r)
{
ans=tree[k].w;
return ;
}
if(tree[k].f) down(k);//懒标记下传,唯一需要更改的地方
int m=(tree[k].l+tree[k].r)/2;
if(x<=m) ask(k*2);
else ask(k*2+1);
}*/
int main()
{
ios::sync_with_stdio(false);
cin >>n;
build(1,n,1);
cin >> m;
for(int i=1;i<=m;i++)
{
cin >> q ;
ans = 0;
if(q==1)
{
cin >> a >> b >> x;
add(1);
}
else
{
cin >> a >> b;
sum(1);
cout << ans << endl;
}
}
}