poj3468 线段树

  http://poj.org/problem?id=3468 题目链接, 很经典的线段树的应用, 这里复习一下, 再写一遍, 代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 100000 + 10;
int N, Q;
int a[maxn];
struct Segment{
    int l, r;
    long long sum;
    int lazy;
}seg[3*maxn];

void build(int rt, int l, int r){
    seg[rt].l = l; seg[rt].r = r;
    seg[rt].lazy = 0;
    if(l==r){
        seg[rt].sum = a[l];
        return ;
    }
    int chl = 2*rt, chr = 2*rt+1;
    int mid = (l+r)/2;
    build(chl, l, mid);
    build(chr, mid+1, r);
    seg[rt].sum = seg[chl].sum + seg[chr].sum;
}

void push_down(int rt){
    int chl = 2*rt, chr = 2*rt+1;
    if(seg[rt].lazy){
        seg[chl].sum += (long long)seg[rt].lazy*(long long)(seg[chl].r-seg[chl].l+1);
        seg[chl].lazy += seg[rt].lazy;
        seg[chr].sum += (long long)seg[rt].lazy*(long long)(seg[chr].r-seg[chr].l+1);
        seg[chr].lazy += seg[rt].lazy;
        seg[rt].lazy = 0;
    }
}

void update(int rt, int l, int r, int c){
    if(seg[rt].l==l && seg[rt].r==r){
        seg[rt].sum += (long long)c*(r-l+1);
        seg[rt].lazy += c;
        return ;
    }
    push_down(rt);
    int mid = (seg[rt].l+seg[rt].r)/2;
    if(r <= mid)
        update(2*rt, l, r, c);
    else if(l>mid)
        update(2*rt+1, l, r, c);
    else{
        update(2*rt, l, mid, c);
        update(2*rt+1, mid+1, r, c);
    }
    seg[rt].sum = seg[2*rt].sum + seg[2*rt+1].sum;
}

long long query(int rt, int l, int r){
    if(seg[rt].l==l && seg[rt].r==r){
        return seg[rt].sum;
    }
    push_down(rt);
    int mid = (seg[rt].l+seg[rt].r)/2;
    if(r <= mid)
        return query(2*rt, l, r);
    else if(l > mid)
        return query(2*rt+1, l, r);
    else {
        long long v1 = query(2*rt, l, mid);
        long long v2 = query(2*rt+1, mid+1, r);
        return v1 + v2;
    }
    seg[rt].sum = seg[2*rt].sum + seg[2*rt+1].sum;
}
int main() {
    scanf("%d%d", &N, &Q);
    for(int i=1; i<=N; i++)
        scanf("%d", &a[i]);
    build(1, 1, N);
    for(int i=0; i<Q; i++){
        char s[6];
        scanf("%s", s);
        if(s[0] == ‘Q‘){
            int l, r;
            scanf("%d%d", &l, &r);
            printf("%lld\n", query(1, l, r));
        }else{
            int l, r, c;
            scanf("%d%d%d", &l, &r, &c);
            update(1, l, r, c);
        }
    }
    return 0;
}
时间: 2024-10-17 17:43:12

poj3468 线段树的相关文章

poj3468 线段树 or splay

poj3468  裸线段树.因为在熟悉splay 所以就用splay交了一发...开始用的scanf()!==2 居然TLE了...然后我就当单组测试数据做的 然后就过了  囧TZ #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> using namespac

poj3468 线段树+lazy标记

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

POJ3468——线段树区间更新——A Simple Problem with Integers

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 numbers in a given interval. Input The firs

POJ-3468(线段树+区间更新+区间查询)

A Simple Problem With Integers POJ-3468 这题是区间更新的模板题,也只是区间更新和区间查询和的简单使用. 代码中需要注意的点我都已经标注出来了,容易搞混的就是update函数里面还需要计算sum数组.因为这里查询的时候是直接用sum查询结点. //区间更新,区间查询 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #inc

poj3468(线段树-区间修改)

模板题: #include<cstdio> #include<cstring> #define ll long long const int N = 100000 + 10; ll sum[N << 2]; ll addv[N << 2]; int num[N]; int n,q; void pushUp(int u) { sum[u] = sum[u * 2] + sum[u * 2 + 1]; } void build(int u, int L, int

POJ3468(线段树区间维护)

#include<cstdio> #define lson n<<1,l,mid #define rson (n<<1)|1,mid+1,r #define gmid (a[n].l+a[n].r)>>1 using namespace std; const int MAX_N=100005; typedef long long LL; struct node{ int l,r; LL sum,lazy; }a[MAX_N<<2]; void P

POJ3468 A Simple Problem with Integers 【线段树】+【成段更新】

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

POJ3468(KB7-C 线段树)

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

POJ-3468 A Simple Problem with Integers(线段树)

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