线段树之各类模板

线段树的认识,可以参考哔哔丽丽的视频。

(1)单点曽减,区间求和

飞翔

#include<stdio.h>
#define lson l,m,rt<<1///左儿子
#define rson m+1,r,rt<<1|1///右儿子
const int maxn = 55555;
int sum[maxn<<2];
void PushUP(int rt)///上一个的值由两个儿子相加
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt)///建立
{
    if(l==r)
    {
        scanf("%d",&sum[rt]);///在建立的过程中赋值
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    PushUP(rt);
}
void update(int p,int add,int l,int r,int rt)
///p点增减add
{
    if(l==r)
    {
       sum[rt]+=add;
       return ;
    }
    int m=(l+r)>>1;
    if(p<=m)
    update(p,add,lson);
    else
    update(p,add,rson);
    PushUP(rt);
}
///LR区间求和
int query(int L,int R,int l,int r,int rt)
{
    if(L <= l && r<=R)
        return sum[rt];
    int m=(l+r)>>1;
    int ret=0;
    if(L <= m )
    ret+=query(L,R,lson);
    if(R > m)
    ret+=query(L,R,rson);
    return ret;
}
int main( )
{
    int a,b,t,n;
    scanf("%d",&t);
    for(int cas=1 ; cas<=t ; cas++)
    {
        printf("Case %d:\n",cas);
        scanf("%d",&n);
        build(1,n,1);
        char op[10];
        while(scanf("%s",op))
        {
            if(op[0]==‘E‘)
            break;
            int a,b;
            scanf("%d%d",&a,&b);
            if(op[0]==‘S‘)
            update(a,-b,1,n,1);
            else if(op[0]==‘Q‘)
            printf("%d\n",query(a,b,1,n,1));
            else
            update(a,b,1,n,1);
        }
    }
    return 0;
}

(2)单点替换,区间最值

飞翔

#include<stdio.h>
#include<algorithm>
using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int manx = 222222;
int MAX[manx<<2];
void PushUP(int rt)///父亲的值由儿子来得出
{
    MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
void build(int l,int r,int rt)
{
    if ( l==r )
    {
        scanf("%d",&MAX[rt]);
        return ;
    }
    int m = (l+r) >> 1;
    build(lson);
    build(rson);
    PushUP(rt);
}
void update(int p,int sc,int l,int r,int rt)
{
    ///p点变为sc
    if (l==r)
    {
        MAX[rt]=sc;
        return ;
    }
    int m=(l+r)>>1;
    if(p <= m )
    update(p,sc,lson);
    else
    update(p,sc,rson);
    PushUP(rt);

}
int query(int L,int R,int l,int r,int rt)
{    ///L到R的最大值
    if(L <= l&&r<= R)
        return MAX[rt];
    int m=(l+r)>>1;
    int ret=0;
    if(L<=m)
    ret=max(ret,query(L,R,lson));
    if(R>m)
    ret=max(ret,query(L,R,rson));
    return ret;
}
int main( )
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        build(1,n,1);
        while(m--)
        {
            char op[2];
            int a,b;
            scanf("%s%d%d",op,&a,&b);
            if(op[0]==‘Q‘)
            printf("%d\n",query(a,b,1,n,1));
            else
            update(a,b,1,n,1);
        }
    }
    return 0;
}

感激这位大牛的模板

原文地址:https://www.cnblogs.com/shuaihui520/p/9069021.html

时间: 2024-10-30 13:26:25

线段树之各类模板的相关文章

线段树 + 区间更新 + 模板 ---- poj 3468

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 59798   Accepted: 18237 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

hdu1698(线段树区间替换模板)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1698 题意: 第一行输入 t 表 t 组测试数据, 对于每组测试数据, 第一行输入一个 n , 表示钩子有 n 节, 编号为 1 ~ n, 每节钩子的初始价值为 1 , 接下来输入一个 q, 接着 q 行输入, 每行格式为 l, r, x, 表示讲区间 [l, r] 内的钩子价值变成 x , 求最终的总价值: 思路: 线段树区间替换模板 代码: 1 #include <iostream> 2 #

HDU 1166 敌兵布阵 (我的树状数组加线段树点修改模板)

思路:本题因为是点修改,所以我们可以用线段树或者是树状数组了.线段树的基本操作我在我的代码中会具体体现,关键是要理解下面这幅图,具体的思想大家可以去看看其他的资料 线段树AC代码: #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; #define N 50005 int num

线段树lazytag优化模板

线段树嘛...很基本的一种数据结构啦 lazytag优化能不错的提高效率 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX=1000000; 4 struct pr { 5 int sum; 6 int lazy; 7 int left,right; 8 }tr[MAX+10]; 9 int n; 10 inline int ll(int k) {return 2*k;} 11 inline int rr(int

线段树区间修改模板

本来打算把大白书第三章一口气攻下来的,但是这个线段树也是卡了好久. 不敢过题太快,怕自己走马观花到头来结果什么都不会. 可也不能再拖了,在做题中也许有更多的体会. 模板一:1 L R v 表示区间[L, R]所有元素都加上v2 L R   表示查询区间[L, R]的sum, min, maxsumv[o]的定义为:如果只执行节点o及其子孙节点的中的add操作,节点o对应区间中所有数之和 1 //线段树区间修改 2 //1 L R v 表示区间[L, R]所有元素都加上v 3 //2 L R 表示

【luogu P3372 线段树1】模板

线段树的模板题 update区间修改,query区间求和 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #define ll long long 5 #define lson left, mid, rt<<1 6 #define rson mid+1, right, rt<<1|1 7 using namespace std; 8 const int maxn

线段树 区间更新模板

一个带区间修改的线段树求和模板: int MAXN = 100005; ll a[100005<<2],ans,p; struct Tree { ll l,r; ll sum,add,mul; } tree[100005<<2]; void pushdown(int tr,int len) { if(len==1) return; long long m=tree[tr].mul,a=tree[tr].add; tree[tr*2].sum=(tree[tr*2].sum*m%p+

线段树(SegmentTree)基础模板

线段树模板题来源:https://www.lintcode.com/problem/segment-tree-build/description 201.?线段树的构造 /** * Definition of SegmentTreeNode: * class SegmentTreeNode { * public: * int start, end; * SegmentTreeNode *left, *right; * SegmentTreeNode(int start, int end) { *

POJ-3468 - A Simple Problem with Integers(线段树区间更新模板)

http://poj.org/problem?id=3468 Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of