线段树3道超级基础模板题
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; } } }

浙公网安备 33010602011771号