#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int MAX=50010;#define Lson L,mid,root<<1 //遇到Lson的时候强制替换为后面的语句#define Rson mid+1,R,root<<1|1int n,sum[MAX<<2];void Pushup(int root) //把当前结点的信息更新到父节点{sum[root]=sum[root<<1]+sum[root<<1|1];}void Build(int L,int R,int root){if(L==R){scanf("%d",&sum[root]);return ;}int mid=(L+R)>>1;Build(Lson); //左孩子Build(Rson); //右孩子Pushup(root);}void Update(int q,int val,int L,int R,int root) //在根为root,区间为[L,R]中的线段树修改结点p的值增加val{if(L==R){sum[root]+=val;return ;}int mid=(L+R)>>1;if(q<=mid) Update(q,val,Lson); //说明p在左结点else Update(q,val,Rson); //说明p在右结点Pushup(root);}int Query(int l, int r, int L, int R, int root){if(l==L && r==R)return sum[root];int mid = (L + R) >> 1;if(r <= mid) return Query(l, r, Lson);else if(l > mid) return Query(l, r, Rson);else return Query(l, mid, Lson) + Query(mid+1, r, Rson);}int main(){int a,b,Case,num=1;scanf("%d",&Case);while(Case--){printf("Case %d:\n",num++);scanf("%d",&n);Build(1,n,1);char op[10];while(scanf("%s",op)){if(op[0]==‘E‘) break;scanf("%d%d",&a,&b);if(op[0]==‘A‘) Update(a,b,1,n,1);if(op[0]==‘S‘) Update(a,-b,1,n,1);if(op[0]==‘Q‘) printf("%d\n",Query(a,b,1,n,1));}}return 0;}
#include <cstdio>#include <cstring>#define maxn 100000 + 10#define Lson L, mid, rt<<1#define Rson mid+1, R, rt<<1|1struct Node{int sum, lazy;} T[maxn<<2];void PushUp(int rt){T[rt].sum = T[rt<<1].sum + T[rt<<1|1].sum;}void PushDown(int L, int R, int rt){int mid = (L + R) >> 1;T[rt<<1].sum = T[rt].lazy * (mid - L + 1);T[rt<<1|1].sum = T[rt].lazy * (R - mid);T[rt<<1].lazy = T[rt].lazy;T[rt<<1|1].lazy = T[rt].lazy;T[rt].lazy = 0;}void Build(int L, int R, int rt){if(L == R){scanf("%d", &T[rt].sum);return ;}int mid = (L + R) >> 1;Build(Lson);Build(Rson);PushUp(rt);}void Update(int l, int r, int v, int L, int R, int rt){if(l==L && r==R){T[rt].lazy = v;T[rt].sum = v * (R - L + 1);return ;}int mid = (L + R) >> 1;if(T[rt].lazy) PushDown(L, R, rt);if(r <= mid) Update(l, r, v, Lson);else if(l > mid) Update(l, r, v, Rson);else{Update(l, mid, v, Lson);Update(mid+1, r, v, Rson);}PushUp(rt);}int Query(int l, int r, int L, int R, int rt){if(l==L && r== R)return T[rt].sum;int mid = (L + R) >> 1;if(T[rt].lazy) PushDown(L, R, rt);if(r <= mid) return Query(l, r, Lson);else if(l > mid) return Query(l, r, Rson);return Query(l, mid, Lson) + Query(mid + 1, r, Rson);}int main(){int n, q;scanf("%d", &n);Build(1, n, 1);scanf("%d", &q);int a, b, c, d;while(q--){scanf("%d%d%d", &a, &b, &c);if(a){scanf("%d", &d);Update(b, c, d, 1, n, 1);}else printf("%d\n", Query(b, c, 1, n, 1));}return 0;}
离散型与连续型的区别:
1.叶子节点:在离散型中,叶子节点是[i, i],而连续性中是[i, i + 1];
2.分解区间:在离散型中,一段区间是分解成为[l, m], [m + 1, r],而在连续型中,是分解成为[l, m], [m, r];
3.其他所有类似的判定问题。
#include <iostream>#include <cstdio>#include <cstring>#include <set>#include <map>using namespace std;#define maxn 100005#define lson L, mid, rt<<1#define rson mid, R, rt<<1|1int a[maxn], b[maxn];int lazy[maxn<<2];int N, L;int left_bound = 1, right_bound;void init(){memset(lazy, -1, sizeof(lazy));right_bound = 0;}void read_compress(){set<int> s;for(int i=1; i<=N; i++){scanf("%d%d", &a[i], &b[i]);s.insert(a[i]);s.insert(b[i]);}map<int, int> m;for(set<int>::iterator it=s.begin(); it!=s.end(); it++)m[*it] = ++right_bound;for(int i=1; i<=N; i++){a[i] = m[a[i]];b[i] = m[b[i]];}}void pushdown(int L, int R, int rt){if(lazy[rt] >= 0)lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];lazy[rt] = -1;}void update(int l, int r, int v, int L, int R, int rt){if(l==L && r==R){lazy[rt] = v;return ;}int mid = (L+R)>>1;if(lazy[rt] >= 0) pushdown(L, R, rt);if(r <= mid) update(l, r, v, lson);else if(l >= mid) update(l, r, v, rson);else{update(l, mid, v, lson);update(mid, r, v, rson);}}void query(int l, int r, int L, int R, int rt, set<int> &s){if(l==L && r==R && lazy[rt]>=0){s.insert(lazy[rt]);return ;}int mid = (L+R)>>1;if(lazy[rt] >= 0) pushdown(L, R, rt);if(r <= mid) query(l, r, lson, s);else if(l >= mid) query(l, r, rson, s);else{query(l, mid, lson, s);query(mid, r, rson, s);}}int main(){while(~scanf("%d%d", &N, &L)){init();read_compress();int cnt = 0;for(int i=1; i<=N; i++)update(a[i], b[i], ++cnt, left_bound, right_bound, 1);cnt = 0;set<int> s;for(int i=1; i<=N; i++)query(a[i], b[i], left_bound, right_bound, 1, s);printf("%d\n", s.size());}return 0;}
线段树区间修改 维护和值、最大值、最小值
#include <cstdio>#include <cstring>#define maxn 100000 + 10#define Lson L, mid, rt<<1#define Rson mid+1, R, rt<<1|1int min(int a, int b) {return a<b ? a : b;}int max(int a, int b) {return a>b ? a : b;}struct Node{int sum, Min, Max, lazy;} T[maxn<<2];void PushUp(int rt){T[rt].sum = T[rt<<1].sum + T[rt<<1|1].sum;T[rt].Min = min(T[rt<<1].Min, T[rt<<1|1].Min);T[rt].Max = max(T[rt<<1].Max, T[rt<<1|1].Max);}void PushDown(int L, int R, int rt){int mid = (L + R) >> 1;int t = T[rt].lazy;T[rt<<1].sum = t * (mid - L + 1);T[rt<<1|1].sum = t * (R - mid);T[rt<<1].Min = T[rt<<1|1].Min = t;T[rt<<1].Max = T[rt<<1|1].Max = t;T[rt<<1].lazy = T[rt<<1|1].lazy = t;T[rt].lazy = 0;}void Build(int L, int R, int rt){if(L == R){scanf("%d", &T[rt].sum);T[rt].Min = T[rt].Max = T[rt].sum;return ;}int mid = (L + R) >> 1;Build(Lson);Build(Rson);PushUp(rt);}void Update(int l, int r, int v, int L, int R, int rt){if(l==L && r==R)//修改区间值{T[rt].lazy = v;T[rt].sum = v * (R - L + 1);T[rt].Min = T[rt].Max = v;return ;}int mid = (L + R) >> 1;if(T[rt].lazy) PushDown(L, R, rt);//向下更新一级if(r <= mid) Update(l, r, v, Lson);else if(l > mid) Update(l, r, v, Rson);else{Update(l, mid, v, Lson);Update(mid+1, r, v, Rson);}PushUp(rt);}int Query(int l, int r, int L, int R, int rt){if(l==L && r== R){printf("(%d, %d)---Min: %d Max: %d Sum: %d \n", L, R, T[rt].Min, T[rt].Max, T[rt].sum);return T[rt].sum;}int mid = (L + R) >> 1;if(T[rt].lazy) PushDown(L, R, rt);if(r <= mid) return Query(l, r, Lson);else if(l > mid) return Query(l, r, Rson);return Query(l, mid, Lson) + Query(mid + 1, r, Rson);}int main(){int n, q;scanf("%d", &n);Build(1, n, 1);scanf("%d", &q);int a, b, c, d;while(q--){scanf("%d%d%d", &a, &b, &c);if(a){scanf("%d", &d);Update(b, c, d, 1, n, 1);}else printf("%d\n", Query(b, c, 1, n, 1));}return 0;}/*61 2 3 4 5 630 1 41 2 3 00 1 4*/
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/dojintian/article/details/46955583