#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|1
int 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|1
struct 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|1
int 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|1
int 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;
}
/*
6
1 2 3 4 5 6
3
0 1 4
1 2 3 0
0 1 4
*/
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/dojintian/article/details/46955583