线段树板子题自用

 

思路:单点修改,区间查询

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0xffffff0;
const int maxn=1000001;
typedef long long ll;
struct Node{
    ll val;
}tree[4*maxn];
ll a[maxn],n,q;
inline void update(ll id){
    tree[id].val=tree[2*id].val+tree[2*id+1].val;
}
ll qurey(ll id,ll l,ll r,ll ql,ll qr){//区间查询板子
    if(l==ql&&r==qr) return tree[id].val;
    ll mid=(l+r)/2;
    if(qr<=mid) return qurey(2*id,l,mid,ql,qr);
    else if(ql>mid) return qurey(2*id+1,mid+1,r,ql,qr);
    else{
        return qurey(2*id,l,mid,ql,mid)+qurey(2*id+1,mid+1,r,mid+1,qr);
    }
}
inline void change(ll id,ll l,ll r,ll pos,ll val){//单点修改板子
    if(l==r){
        tree[id].val+=val;
    } else{
        ll mid=(l+r)/2;
        if(pos<=mid) change(id*2,l,mid,pos,val);
        else change(id*2+1,mid+1,r,pos,val);
        update(id);
    }
}
inline void build(ll id,ll l,ll r){
    if(l==r){
        tree[id].val=a[l];return;
    } 
    ll mid=(l+r)/2;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
    update(id);
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);std::cout.tie(0);
    cin>>n>>q;
    for(ll i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    for(ll i=1;i<=q;i++){
        ll mod;cin>>mod;
        if(mod==1){
            ll x;ll d;cin>>x>>d;
            change(1,1,n,x,d);
        } else{
            ll l,r;cin>>l>>r;
            ll num=qurey(1,1,n,l,r);
            cout<<num<<"\n";
        }
    }
    return 0;
}

 

 

 

 思路:单点修改,区间查询,利用重载运算符统计最小数数量

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0xffffff0;
const int maxn=200001;
struct info{
    int minv,cnt;
};
info operator + (const info &l,const info &r){
    info a;
    a.minv=min(l.minv,r.minv);
    if(l.minv==r.minv) a.cnt=l.cnt+r.cnt;
    else if(l.minv<r.minv) a.cnt=l.cnt;
    else a.cnt=r.cnt;
    return a;
}
struct Node{
    info val;
}tree[4*maxn];
int a[maxn],n,q;
inline void update(int id){
    tree[id].val=tree[2*id].val+tree[2*id+1].val;
}
info qurey(int id,int l,int r,int ql,int qr){//区间查询板子
    if(l==ql&&r==qr) return tree[id].val;
    int mid=(l+r)/2;
    if(qr<=mid) return qurey(2*id,l,mid,ql,qr);
    else if(ql>mid) return qurey(2*id+1,mid+1,r,ql,qr);
    else{
        return qurey(2*id,l,mid,ql,mid)+qurey(2*id+1,mid+1,r,mid+1,qr);
    }
}
inline void change(int id,int l,int r,int pos,int val){//单点修改板子
    if(l==r){
        tree[id].val={val,1};
    } else{
        int mid=(l+r)/2;
        if(pos<=mid) change(id*2,l,mid,pos,val);
        else change(id*2+1,mid+1,r,pos,val);
        update(id);
    }
}
inline void build(int id,int l,int r){
    if(l==r){
        tree[id].val={a[l],1};return;
    } 
    int mid=(l+r)/2;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
    update(id);
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);std::cout.tie(0);
    cin>>n>>q;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    for(int i=1;i<=q;i++){
        int mod;cin>>mod;
        if(mod==1){
            int x,d;cin>>x>>d;
            change(1,1,n,x,d);
        } else{
            int l,r;cin>>l>>r;
            info num=qurey(1,1,n,l,r);
            cout<<num.minv<<' '<<num.cnt<<"\n";
        }
    }
    return 0;
}

 

posted on 2022-06-05 15:46  zesure  阅读(25)  评论(0编辑  收藏  举报

导航