• CodeForces


    题目链接:https://codeforces.com/problemset/problem/438/D

    题目大意:给你n个数,有三种操作,一是对区间$[l,r]$求和,二是对区间$[l,r]$中每个数对$x$取模,三是单点修改。

    Examples

    Input
    5 5
    1 2 3 4 5
    2 3 5 4
    3 3 5
    1 2 5
    2 1 3 3
    1 1 3
    Output
    8
    5
    Input
    10 10
    6 9 6 7 6 1 10 10 9 5
    1 3 9
    2 7 10 9
    2 5 10 8
    1 4 7
    3 3 7
    2 7 9 9
    1 2 4
    1 6 6
    1 5 9
    3 1 10
    Output
    49
    15
    23
    1
    9

    emmmm,一和三没什么好说的,就是第二个操作可能有点小问题,最为暴力的写法就是每个点都取模,不过这样的话就很费时间,会T掉,那么我们要去优化,想到之前我们写过的吉司机线段树,维护最大值和次大值,那么我们也可以这么想,如果取模的数大于最大值就直接return了,然后对于次大值的时候单独讨论,其他的全部更新到根节点。只不过本题的次大值维护有点麻烦。。。所以尝试一波只维护最大值,交一发。。。A了!!!

    以下是AC代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define lc rt<<1
    #define rc rt<<1|1
    typedef long long ll;
    const int mac=1e5+10;
    const int inf=1e9+10;
    
    ll sum[mac<<2];
    int mx[mac<<2];
    
    void update_range(int l,int r,int rt,int L,int R,int mod)
    {
        if (mod>mx[rt]) return;
        if (l==r) {
            sum[rt]=mx[rt]=mx[rt]%mod;
            return;
        }
        int mid=(l+r)>>1;
        if (mid>=L) update_range(lson,L,R,mod);
        if (mid<R) update_range(rson,L,R,mod);
        sum[rt]=sum[lc]+sum[rc];
        mx[rt]=max(mx[lc],mx[rc]);
    }
    
    void update_point(int l,int r,int rt,int pos,int x)
    {
        if (l==r) {sum[rt]=x; mx[rt]=x; return;}
        int mid=(l+r)>>1;
        if (mid>=pos) update_point(lson,pos,x);
        else update_point(rson,pos,x);
        sum[rt]=sum[lc]+sum[rc];
        mx[rt]=max(mx[lc],mx[rc]);
    }
    
    ll query(int l,int r,int rt,int L,int R)
    {
        ll ans=0;
        if (l>=L && r<=R) return sum[rt];
        int mid=(l+r)>>1;
        if (mid>=L) ans+=query(lson,L,R);
        if (mid<R) ans+=query(rson,L,R);
        return ans;
    }
    
    void build(int l,int r,int rt)
    {
        if (l==r){
            int x;
            scanf ("%d",&x);
            mx[rt]=sum[rt]=x;
            return;
        }
        int mid=(l+r)>>1;
        build(lson);build(rson);
        sum[rt]=sum[lc]+sum[rc];
        mx[rt]=max(mx[lc],mx[rc]);
    }
    
    int  main()
    {
        //freopen("in.txt","r",stdin);
        int n,q;
        scanf ("%d%d",&n,&q);
        build(1,n,1);
        while (q--){
            int opt,l,r,x,pos;
            scanf ("%d",&opt);
            if (opt==1){
                scanf ("%d%d",&l,&r);
                printf("%lld
    ",query(1,n,1,l,r));
            }
            else if (opt==2){
                scanf ("%d%d%d",&l,&r,&x);
                update_range(1,n,1,l,r,x);
            }
            else {
                scanf ("%d%d",&pos,&x);
                update_point(1,n,1,pos,x);
            }
        }
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    蚂蚁森林自动收能量
    え速记
    い 速记
    あ速记
    五十音图
    Leetcode 215. 数组中的第K个最大元素 排序 优先队列
    动手学深度学习 | 第二部分完结竞赛:图片分类 | 29
    动手学深度学习 | 残差网络 ResNet | 27
    动手学深度学习 | 批量归一化 | 26
    动手学深度学习 | 含并行连结的网络GoogLeNet/Inception V3 | 25
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13277103.html
Copyright © 2020-2023  润新知