线段树模版

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
#include <map>
#include <queue>
#include <string>
#define maxn 8080
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ALL %I64d
using namespace std;
typedef long long  ll;

//线段树的定义
struct segment
{
    int l,r;
    int value;
    int nv;
} son[maxn<<2];

//PushUP函数
void PushUp(int rt)
{
    son[rt].value=son[rt<<1].value+son[rt<<1|1].value;
}

//PushDown函数
void PushDown(int rt)
{
    if(son[rt].nv)
    {
        son[rt<<1].nv+=son[rt].nv;
        son[rt<<1|1].nv+=son[rt].nv;
        //son[rt<<1].value+=(son[rt<<1].r-son[rt<<1].l+1)*son[rt].nv;
        //son[rt<<1|1].value+=(son[rt<<1|1].r-son[rt<<1|1].l+1)*son[rt].nv;
        son[rt].nv=0;
    }
}

//建立线段树
void Build(int l,int r,int rt)
{
    son[rt].l=l;
    son[rt].r=r;
    if(l==r)
    {
        son[rt].value=1;
        return;
    }
    int m=(l+r)/2;
    Build(lson);
    Build(rson);
    PushUp(rt);
}

//线段树单点更新
void Update_1(int p,int value,int rt)
{
    if(son[rt].l==son[rt].r)
    {
        son[rt].value=value;
        return;
    }

    PushDown(rt);

    int m=(son[rt].l+son[rt].r)/2;
    if(p<=m)
        Update_1(p,value,rt<<1);
    else
        Update_1(p,value,rt<<1|1);

    PushUp(rt);
}

//线段树区间更新
void Update_n(ll w,int l,int r,int rt)
{
    if(son[rt].l==l&&son[rt].r==r)
    {
        son[rt].value+=w*(r-l+1);
        son[rt].nv+=w;
        return;
    }

    PushDown(rt);

    int m=(son[rt].l+son[rt].r)/2;

    if(r<=m)
        Update_n(w,l,r,rt<<1);
    else if(l>m)
        Update_n(w,l,r,rt<<1|1);
    else
    {
        Update_n(w,lson);
        Update_n(w,rson);
    }
    PushUp(rt);
}

//线段树插入位置查找并插入
int Update(int w,int rt)
{
    if(son[rt].l==son[rt].r)
    {
        son[rt].value=0;
        return son[rt].l;
    }

    int m=(son[rt].l+son[rt].r)/2,ret=0;

    if(son[rt<<1].value>w)
        ret=Update(w,rt<<1);
    else
    {
        w-=son[rt<<1].value;
        ret=Update(w,rt<<1|1);
    }
    PushUp(rt);
    return ret;
}

//区间查询函数
ll  Query(int l,int r,int rt)
{
    if(son[rt].l==l&&son[rt].r==r)
    {
        return son[rt].value;
    }

    PushDown(rt);

    ll ret=0;
    int m=(son[rt].l+son[rt].r)/2;

    if(r<=m)
        ret=Query(l,r,rt<<1);
    else if(l>m)
        ret=Query(l,r,rt<<1|1);
    else
    {
        ret=Query(lson);
        ret+=Query(rson);
    }
    //PushUp(rt);
    return ret;
}

int main()
{

    return 0;
}

线段树模版

时间: 2024-08-29 07:38:01

线段树模版的相关文章

二维线段树模版

HDU 4819 二维线段树模版题 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int INF = 999999999; const int maxn = 810; int a[maxn][maxn]; int st_min[maxn<<2][maxn<<2]; int st_max[maxn<<2][maxn

线段树模版(转)

//=========================================== //segment tree //final version //by kevin_samuel(fenice)苏州大学孙俊彦 #include <iostream> #include <cstdio> #include <cmath> using namespace std; #define MAXN 100 #define INF 0x3fffffff int A[MAXN]

51Nod—1174 区间中最大的数 线段树模版

在大佬们题解的帮助下算是看懂了线段树吧...在这mark下防一手转头就忘. #include<iostream> #include<stdio.h> using namespace std; struct ki { int m,l,r; }tree[40005]; int ans=-1,a[10005]; void build(int n,int l,int r) { tree[n].l=l; tree[n].r=r; if(l==r) { tree[n].m=a[l];retur

C - A Simple Problem with Integers POJ - 3468 线段树模版(区间查询区间修改)

参考qsc大佬的视频 太强惹 先膜一下 视频在b站 直接搜线段树即可 1 #include<cstdio> 2 using namespace std; 3 const int maxn=1e5+6; 4 int n,a[maxn]; 5 struct Node{ 6 int l,r; 7 long long sum,lazy; 8 void update(long long x){//用于更新区间和 和懒标记 9 sum+=1ll*(r-l+1)*x; 10 lazy+=x; 11 } 12

HDU 1556 Color the ball 线段树

HDU 1556 Color the ball 线段树模版题,存个模板 1 #include <iostream> 2 #include <cstdio> 3 #include <fstream> 4 #include <algorithm> 5 #include <cmath> 6 #include <deque> 7 #include <vector> 8 #include <queue> 9 #inclu

线段树 (区间修改 区间查询 延迟标记)

hdu 1698 Just a Hook 题意: 给你一链子,这天链子由金银铜三种钩子组成,每种钩子都有自己的价值,起初,这条钩子全部由铜钩子组成,给你两个数n(钩子的个数),Q(操作的个数)每次操作就是将给定区间里的数变成某种钩子,求这条链子的总价值. 分析: 线段树模版题,处理好延迟标记即可. 代码: #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #in

HDU 2795 Billboard (线段树单点更新 &amp;&amp; 求区间最值位置)

题意 : 有一块 h * w 的公告板,现在往上面贴 n 张长恒为 1 宽为 wi 的公告,每次贴的地方都是尽量靠左靠上,问你每一张公告将被贴在1~h的哪一行?按照输入顺序给出. 分析 : 这道题说明了每一次贴都尽量选择靠上靠左的位置,那既然这样,我们以1~h建立线段树,给每一个叶子节点赋值初值 w 表示当前行最大能够容纳宽度为 w 的公告纸,那么对于某一输入 wi 只要在线段树的尽量靠左的区间找出能够容纳这张公告的位置(即叶子节点)然后减去 wi 即可,需要对query()函数进行一点改造,将

线段树,最大值查询位子(个人模版)

线段树,最大值查询位子: 1 #include<cstdio> 2 #include<climits> 3 #include<algorithm> 4 5 using namespace std; 6 7 #define lson l, m, rt<<1 8 #define rson m+1, r, (rt<<1)|1 9 10 int tree[111111<<2]; 11 int posn[111111<<2]; 12

HDU 1754 I Hate It(线段树之单点更新,区间最值)

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 70863    Accepted Submission(s): 27424 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感.不管你喜不喜欢,现在需要你做的是,就是按照老师的