hiho1080 - 数据结构 线段树(入门题,两个lazy tag)

题目链接

维护区间和,两个操作:一个是将某个区间设置成一个值,一个是将某个区间增加一个固定值

/**************************************************************/

每走到一个区间就把lazy tag下放。下放的时候注意顺序!

#include <cstdio>
#include <cstring>
const int N = 100100;
struct NODE{
     int l,r;
     int sum;
     int setTo,add;
     NODE(){setTo=add=0;}
     int length(){return (r-l+1);}
};
int data[N];
NODE segtree[N*3];

void build(int id,int l,int r){
     segtree[id].l = l;
     segtree[id].r = r;
     if(l==r){
        segtree[id].sum = data[l];
        return ;
     }
     int mid = (l+r)>>1;
     build(id*2+0,l,mid);
     build(id*2+1,mid+1,r);
     segtree[id].sum = segtree[id*2+0].sum+segtree[id*2+1].sum;
}

void modify(int id,int spos,int epos,int value,int type){
     if(segtree[id].l==spos&&segtree[id].r==epos){
        if(type){
            segtree[id].setTo = value;
            segtree[id].add = 0;
            segtree[id].sum = segtree[id].length()*value;
        }
        else{
            segtree[id].add += value;
            segtree[id].sum += segtree[id].length()*value;
        }
        return ;
     }

     //push down
     if(segtree[id].setTo){
        segtree[id*2+0].setTo=segtree[id*2+1].setTo=segtree[id].setTo;
        segtree[id*2+0].add=segtree[id*2+1].add=0;
        segtree[id*2+0].sum = segtree[id*2+0].length()*segtree[id*2+0].setTo;
        segtree[id*2+1].sum = segtree[id*2+1].length()*segtree[id*2+1].setTo;
        segtree[id].setTo = 0;
     }
     if(segtree[id].add){
        segtree[id*2+0].add += segtree[id].add;
        segtree[id*2+1].add += segtree[id].add;
        segtree[id*2+0].sum += segtree[id*2+0].length()*segtree[id].add;
        segtree[id*2+1].sum += segtree[id*2+1].length()*segtree[id].add;
        segtree[id].add = 0;
     }

     int mid = (segtree[id].l+segtree[id].r)>>1;
     if(epos<=mid) modify(id*2,spos,epos,value,type);
     else if(spos>mid) modify(id*2+1,spos,epos,value,type);
     else{
        modify(id*2+0,spos,mid,value,type);
        modify(id*2+1,mid+1,epos,value,type);
     }

     segtree[id].sum = segtree[id*2+0].sum+segtree[id*2+1].sum;
}
int main(){
    int n,t;
    scanf("%d%d",&n,&t); n++;
    for(int i=1;i<=n;i++) scanf("%d",data+i);
    build(1,1,n);
    while(t--){
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        modify(1,b+1,c+1,d,a);
        printf("%d\n",segtree[1].sum);
    }
    return 0;
}
时间: 2024-10-12 11:22:27

hiho1080 - 数据结构 线段树(入门题,两个lazy tag)的相关文章

线段树入门题 hdu1166 敌兵布阵

题意:动态查询一段区间的和,支持单点更新. 开始刷线段树了,这是入门第一题...最基本的线段树操作,递归建树,递归查询,递归修改,向上更新节点,每个节点的值代表该节点对应区间的和 . 代码:

[poj2104]可持久化线段树入门题(主席树)

解题关键:离线求区间第k小,主席树的经典裸题: 对主席树的理解:主席树维护的是一段序列中某个数字出现的次数,所以需要预先离散化,最好使用vector的erase和unique函数,很方便:如果求整段序列的第k小,我们会想到离散化二分和线段树的做法, 而主席树只是保存了序列的前缀和,排序之后,对序列的前缀分别做线段树,具有差分的性质,因此可以求任意区间的第k小,如果主席树维护索引,只需要求出某个数字在主席树中的位置,即为sort之后v中的索引:若要求第k大,建树时反向排序即可 1 #include

线段树入门题

//hdu1754 #include<stdio.h> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 //注意因为这里右边是+1的,所以在下面更新以及查询时要注意是否要加=号!!! #define maxn 200020 int sum[maxn<<2],a[maxn]; int max(int x,int y) { return x>y?x:y; } void PushUP(int rt) { s

【整理】线段树30题

1,poj 1151 Atlantis: 求矩形面积并. 2,poj 1177 Picture: 求矩形轮廓的周长. 3,poj 1389 Area of Simple Polygons :同第一题. 4,poj 1823 Hotel :线段树线段的插入删除求线段树中最长的线段长度 5,poj 2104 K-th Number:线段树维护归并排序树+三次二分查找   (区间第k大 ,主席树也行,前者可以练习试一下). 6,poj 2155 Matrix :求二维平面的矩形信息,二维线段树,或者二

线段树入门(更新单个节点)

很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时候需要更新某位同学的成绩. Input本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目. 学生ID编号分别从1编到N. 第二行包含N个整数,代表这N个学生的初始成绩,

《数据结构》线段树入门(二)

今天继续介绍——线段树之延迟标记 接上期<数据结构>线段树入门(一):http://www.cnblogs.com/shadowland/p/5870339.html 在上期介绍了线段树的最基本内容(线段树单点修改,区间查询),这次将介绍:区间修改,区间查询. Question: 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述: 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,每行表示操作的个数,如果第一数是1,后接3个正

《数据结构》线段树入门(一)

今天介绍一种非常特殊的数据结构——线段树 首先提出一个问题: 给你n个数,有两种操作: 1:给第i个数的值增加X 2:询问区间[a,b]的总和是什么? 输入描述 输入文件第一行为一个整数n,接下来是n行n个整数,表示格子中原来的整数.接下一个正整数q,再接 下来有q行,表示q个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给 位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和. 样例输入 4 7 6 3 5 2 1 1

线段树入门小结

QUE:线段树? 称谓: 从刘汝佳的书中得知,"这种数据结构在学术界没有统一的术语,但线段树是最常见的叫法.其他叫法包括区间树(interval tree).范围树(range tree)等,但这些属于在特定的场合(如计算几何)中有着特殊的意义".怎么叫看读者的心情,以下统一用线段树称呼. 先来作一些了解: 线段树是一棵二叉树,它的左右儿子也都是一棵线段树.(定义) 线段树也叫区间树,为什么叫它区间树呢?因为线段树是一种基于区间的数据结构. 线段树的每个节点代表一个区间 [L,R],其

线段树入门(I Hate It)

I Hate It Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时候需要更新某位同学的成绩. Input 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,