• 438D


    #include <stdio.h>
    #include <algorithm>
     
    using namespace std;
     
    #define lson num << 1
    #define rson num << 1 | 1
    #define MAXN 100005
    typedef long long ll;
     int a[MAXN << 1];
    struct node
    {
        int l,r;
        ll Max,sum;
    }tree[MAXN << 2];
    void pushup(ll rt){
        
        tree[rt].Max = max(tree[rt << 1].Max,tree[rt << 1|1].Max);
        tree[rt].sum = tree[rt << 1].sum + tree[rt << 1|1].sum;
    }
    
    // void build(int num,int l,int r)
    // {
    //     tree[num].l = l;
    //     tree[num].r = r;
    //     if(l == r) {
    //         //scanf("%I64d",&tree[num].Max);
    //         tree[num].sum = tree[num].Max = a[l];
    //         return;
    //     }
    //     int mid = (l + r) >> 1;
    //     build(lson,l,mid);
    //     build(rson,mid + 1,r);
    //     pushup(num);
    // }
    void build(ll rt,ll l ,ll r){
        tree[rt].l = l , tree[rt].r = r;
        if(l == r){
            tree[rt].sum = tree[rt].Max = a[l];
            return;
        }
        ll mid = (l + r) >> 1;
        build(rt << 1, l , mid);
        build(rt <<1|1,mid + 1,r);
    
        pushup(rt);
    }
    
     
    // ll query(int num,int l,int r)
    // {
    //     if(tree[num].l == l && tree[num].r == r) {
    //         return tree[num].sum;
    //     }
    //     int mid = (tree[num].l + tree[num].r) >> 1;
    //     if(r <= mid) {
    //         return query(lson,l,r);
    //     }
    //     else if(l > mid) {
    //         return query(rson,l,r);
    //     }
    //     else {
    //         return query(lson,l,mid) + query(rson,mid + 1,r);
    //     }
    // }
    ll query(ll rt,ll l,ll r){
        if(tree[rt].l == l && r == tree[rt].r){
            return tree[rt].sum;
        }//cout << rt << endl;
        ll mid = (tree[rt].l + tree[rt].r) >> 1;
        if(r <= mid) return query(rt << 1,l ,r);
        else if(l > mid) return query(rt << 1|1,l,r);
        else return query(rt << 1,l, mid) + query(rt << 1|1 , mid + 1, r);
    }
    
    // void update1(int num,int l,int r,int mod)
    // {
    //     if(tree[num].Max < mod) {
    //         return;
    //     }
    //     if(tree[num].l == tree[num].r) {
    //         tree[num].Max %= mod;
    //         tree[num].sum %= mod;
    //         return;
    //     }
    //     int mid = (tree[num].l + tree[num].r) >> 1;
    //     if(r <= mid) {
    //         update1(lson,l,r,mod);
    //     }
    //     else if(l > mid) {
    //         update1(rson,l,r,mod);
    //     }
    //     else {
    //         update1(lson,l,mid,mod),update1(rson,mid + 1,r,mod);
    //     }
    //     pushup(num);
    // }
    
    void update1(ll rt,ll l ,ll r ,ll v){
       // cout << t[rt].maxx << endl;
        if(v > tree[rt].Max) return;
        if( tree[rt].l == tree[rt].r){
           
            tree[rt].Max %= v; tree[rt].sum  %= v;
           // cout << t[rt].sum << " " << 111 << endl;
            return;
        }
        
        //
        ll mid = (tree[rt].l + tree[rt].r) >> 1;
        if(r <= mid) update1(rt << 1,l ,r,v);
        else if(l > mid) update1(rt << 1|1,l,r,v);
        else update1(rt << 1,l, mid,v) , update1(rt << 1|1 , mid + 1, r,v);
        pushup(rt);
    }
    
    // void update2(int num,int pos,int val)
    // {
    //     if(tree[num].l == tree[num].r && tree[num].l == pos) {
    //         tree[num].sum = val;
    //         tree[num].Max = val;
    //         return;
    //     }
    //     int mid = (tree[num].l + tree[num].r) >> 1;
    //     if(pos <= mid) {
    //         update2(lson,pos,val);
    //     }
    //     else {
    //         update2(rson,pos,val);
    //     }
    //     pushup(num);
    // }
    
    
    
    void update2(ll rt,ll x,ll v){
        if(tree[rt].l == tree[rt].r && tree[rt].l == x){
            tree[rt].Max = tree[rt].sum = v;
            return;
        }
        ll mid = (tree[rt].l + tree[rt].r) >> 1;
        if(x <= mid) update2(rt << 1,x , v);
        else update2(rt << 1|1,x , v);
        pushup(rt);
    }
    
    
    // int main(void)
    // {
    //     int n,m;
    //     scanf("%d%d",&n,&m);
    //     for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
    //     build(1,1,n);
    //     while(m--) {
    //         int op,l,r,pos,x;
    //         scanf("%d",&op);
    //         if(op == 1) {
    //             scanf("%d%d",&l,&r);
    //             printf("%I64d
    ",query(1,l,r));
    //         }
    //         else if(op == 2) {
    //             scanf("%d%d%d",&l,&r,&x);
    //             update1(1,l,r,x);
    //         }
    //         else {
    //             scanf("%d%d",&pos,&x);
    //             update2(1,pos,x);
    //         }
     
    //     }
    //     return 0;
    // }
    
    int main(int argc, char const *argv[])
    {
        ll n , m ;
        scanf("%lld%lld",&n,&m);
        for(ll i = 1;i <= n ; i++) scanf("%lld",&a[i]);
        build(1,1,n);
    //for(ll i = 1;i <= 40; i++) cout << t[i].sum << endl;
        while(m--){
            ll a;
            scanf("%lld",&a);
            if(a == 1){
                ll b , c;
                scanf("%lld%lld",&b,&c);
                printf("%lld
    ",query(1,b,c));
            }else if(a == 2){
                ll b ,c, pos;
                scanf("%lld%lld%lld",&b,&c,&pos);
                update1(1,b,c,pos);
            }else{
                ll b , c;
                scanf("%lld%lld",&b,&c);
                update2(1,b,c);
            }
        }
        return 0;
    }

     线段树重要思想

     线段树单点修改的本质就是区间修改

    本题是对所有数取模,如果对区间和取模,必定会影响子节点,那么便只能对子节点取模

    但是如果一个一个取模,便会有超时的危险

    那么我们就可以利用剪枝的思想,对小于mod的数/区间,直接返回

    只对大于mod的数进行取模,那么便能降低复杂度。

    #include <stdio.h>
    #include <algorithm>
     
    using namespace std;
     
    #define lson num << 1
    #define rson num << 1 | 1
    #define MAXN 100005
    typedef long long ll;
     
    struct node
    {
        int l,r;
        ll Max,sum;
    }tree[MAXN << 2];
    void pushup(int num)
    {
        tree[num].Max = max(tree[lson].Max,tree[rson].Max);
        tree[num].sum = tree[lson].sum + tree[rson].sum;
    }
    void build(int num,int l,int r)
    {
        tree[num].l = l;
        tree[num].r = r;
        if(l == r) {
            scanf("%I64d",&tree[num].Max);
            tree[num].sum = tree[num].Max;
            return;
        }
        int mid = (l + r) >> 1;
        build(lson,l,mid);
        build(rson,mid + 1,r);
        pushup(num);
    }
    ll query(int num,int l,int r)
    {
        if(tree[num].l >= l && tree[num].r <= r) {
            return tree[num].sum;
        }
        int mid = (tree[num].l + tree[num].r) >> 1;
        if(r <= mid) {
            return query(lson,l,r);
        }
        else if(l > mid) {
            return query(rson,l,r);
        }
        else {
            return query(lson,l,mid) + query(rson,mid + 1,r);
        }
    }
    void update1(int num,int l,int r,int mod)
    {
        if(tree[num].Max < mod) {
            return;
        }
        //因为修改的是最大值,不是区间修改,所以是这个
        if(tree[num].l == tree[num].r) {
            tree[num].Max %= mod;
            tree[num].sum %= mod;
            return;
        }
        int mid = (tree[num].l + tree[num].r) >> 1;
        if(r <= mid) {
            update1(lson,l,r,mod);
        }
        else if(l > mid) {
            update1(rson,l,r,mod);
        }
        else {
            update1(lson,l,mid,mod),update1(rson,mid + 1,r,mod);
        }
        pushup(num);
    }
    void update2(int num,int pos,int val)
    {
        if(tree[num].l == tree[num].r ) {
            tree[num].sum = val;
            tree[num].Max = val;
            return;
        }
        int mid = (tree[num].l + tree[num].r) >> 1;
        if(pos <= mid) {
            update2(lson,pos,val);
        }
        else {
            update2(rson,pos,val);
        }
        pushup(num);
    }
    int main(void)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,1,n);
        while(m--) {
            int op,l,r,pos,x;
            scanf("%d",&op);
            if(op == 1) {
                scanf("%d%d",&l,&r);
                printf("%I64d
    ",query(1,l,r));
            }
            else if(op == 2) {
                scanf("%d%d%d",&l,&r,&x);
                update1(1,l,r,x);
            }
            else {
                scanf("%d%d",&pos,&x);
                update2(1,pos,x);
            }
     
        }
        return 0;
    }
  • 相关阅读:
    Spoj-DWARFLOG Manipulate Dwarfs
    Spoj-DRUIDEOI Fata7y Ya Warda!
    LightOJ1106 Gone Fishing
    LightOJ1125 Divisible Group Sums
    hdu5396 Expression
    cf715B Complete The Graph
    cf601A The Two Routes
    cf602B Approximating a Constant Range
    cf602A Two Bases
    认证方式
  • 原文地址:https://www.cnblogs.com/Agnel-Cynthia/p/11198153.html
Copyright © 2020-2023  润新知