线段树3道超级基础模板题

CODEVS 1080 线段树练习 http://codevs.cn/problem/1080/ 

 单点修改 区间查询

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f;
const int maxn = 1e5+5;
using namespace std;
struct node
{
    int l,r,w;
}tree[4*maxn];

int n,m;
int q,x,y;
int ans ;

void build(int l ,int r ,int k)
{
    tree[k].l = l; tree[k].r = r;
    if(l==r)    {cin >> tree[k].w; return ;}
    int m = (l+r)/2;
    build(l,m,k*2);
    build(m+1,r,k*2+1);
    tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
void sum(int k)
{
    if(tree[k].l >=x  &&  tree[k].r<=y)
    {
        ans+= tree[k].w;
        return ;
    }
    int m = (tree[k].l+tree[k].r)/2;
    if(x<=m) sum(k*2);
    if(y>m) sum(k*2+1);
}
void add(int k )
{
    if(tree[k].l == tree[k].r)
    {
        tree[k].w += y;
        return ;
    }
    int m = (tree[k].l+tree[k].r)/2;
    if(x<=m) add(k*2);
    else add(k*2+1);
    tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
int main()
{
    ios::sync_with_stdio(false);
    cin >>n;
    build(1,n,1);
    cin >> m;
    for(int i=1;i<=m;i++)
    {
        cin >> q >> x >> y;
        ans  = 0;
        if(q==1)  add(1);
        else
        {
            sum(1);
            cout << ans << endl;
        }
    }
}

 

CODEVS 1081 线段树练习 2 http://codevs.cn/problem/1081/

区间修改 单点查询 (懒标记)

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f;
const int maxn = 1e5+5;
using namespace std;
struct node
{
    int l,r,w,f;
}tree[4*maxn];

int n,m;
int q,x,y;
int ans ;
int a,b;

void build(int l ,int r ,int k)
{
    tree[k].l = l; tree[k].r = r;
    if(l==r)    {cin >> tree[k].w; return ;}
    int m = (l+r)/2;
    build(l,m,k*2);
    build(m+1,r,k*2+1);
    tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
void sum(int k)
{
    if(tree[k].l >=x  &&  tree[k].r<=y)
    {
        ans+= tree[k].w;
        return ;
    }
    int m = (tree[k].l+tree[k].r)/2;
    if(x<=m) sum(k*2);
    if(y>m) sum(k*2+1);
}
void down(int k) //下传标记
{
    tree[k*2].f+=tree[k].f;
    tree[k*2+1].f+=tree[k].f;

    tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
  tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);

    tree[k].f = 0;
}
void add(int k )
{
    if(tree[k].l>=a && tree[k].r<=b)
    {
        tree[k].w += x *(tree[k].r -tree[k].l+1);
        tree[k].f += x;
        return ;
    }
    if(tree[k].f) down(k);
    int m = (tree[k].l+tree[k].r)/2;
    if(a<=m) add(k*2);
    if(b>m) add(k*2+1);
    tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
void ask(int k)//单点查询
{
    if(tree[k].l==tree[k].r)
    {
        ans=tree[k].w;
        return ;
    }
    if(tree[k].f) down(k);//懒标记下传,唯一需要更改的地方
    int m=(tree[k].l+tree[k].r)/2;
    if(x<=m) ask(k*2);
    else ask(k*2+1);
}
int main()
{
    ios::sync_with_stdio(false);
    cin >>n;
    build(1,n,1);
    cin >> m;
    for(int i=1;i<=m;i++)
    {
        cin >> q ;
        ans  = 0;
        if(q==1)
        {
            cin >> a >> b >> x;
            add(1);
        }
        else
        {
            cin >> x;
            ask(1);
            cout << ans << endl;
        }
    }
}

 

CODEVS 1081 线段树练习 3 http://codevs.cn/problem/1082/

区间更新 区间查询(懒标记)

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f;
#define ll long long 
const int maxn = 2e5+5;
using namespace std;
struct node
{
    ll l,r,w,f;
}tree[4*maxn];

int n,m;
int q,x,y;
ll ans ;
int a,b;

void build(int l ,int r ,int k)
{
    tree[k].l = l; tree[k].r = r;
    if(l==r)    {cin >> tree[k].w; return ;}
    int m = (l+r)/2;
    build(l,m,k*2);
    build(m+1,r,k*2+1);
    tree[k].w = tree[k*2].w + tree[k*2+1].w;
}

void down(int k) //下传标记
{
    tree[k*2].f+=tree[k].f;
    tree[k*2+1].f+=tree[k].f;

    tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
      tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);

    tree[k].f = 0;
}
void sum(int k)
{
    if(tree[k].l >=a  &&  tree[k].r<=b)
    {
        ans+= tree[k].w;
        return ;
    }
    if(tree[k].f) down(k);
    int m = (tree[k].l+tree[k].r)/2;
    if(a<=m) sum(k*2);
    if(b>m) sum(k*2+1);
}
void add(int k )
{
    if(tree[k].l>=a && tree[k].r<=b)
    {
        tree[k].w += x *(tree[k].r -tree[k].l+1);
        tree[k].f += x;
        return ;
    }
    if(tree[k].f) down(k);
    int m = (tree[k].l+tree[k].r)/2;
    if(a<=m) add(k*2);
    if(b>m) add(k*2+1);
    tree[k].w = tree[k*2].w + tree[k*2+1].w;
}
/*void ask(int k)//单点查询
{
    if(tree[k].l==tree[k].r)
    {
        ans=tree[k].w;
        return ;
    }
    if(tree[k].f) down(k);//懒标记下传,唯一需要更改的地方
    int m=(tree[k].l+tree[k].r)/2;
    if(x<=m) ask(k*2);
    else ask(k*2+1);
}*/
int main()
{
    ios::sync_with_stdio(false);
    cin >>n;
    build(1,n,1);
    cin >> m;
    for(int i=1;i<=m;i++)
    {
        cin >> q ;
        ans  = 0;
        if(q==1)
        {
            cin >> a >> b >> x;
            add(1);
        }
        else
        {
            cin >> a >> b;
            sum(1);
            cout << ans << endl;
        }
    }
}

 

posted @ 2018-08-17 00:14  llke  阅读(102)  评论(0)    收藏  举报