维护区间最大最小值和区间和做法
查看原帖
维护区间最大最小值和区间和做法
304558
TheShuMo楼主2023/9/12 19:45

RT,用树状数组和线段树各写了一遍,全是10分,我不能理解/yiw。

#include<bits/stdc++.h>
#define int long long
#define pb push_back

namespace IO {
    #define int long long 
    #define gh getchar
    inline int read(){char ch=gh();int x=0;bool t=0;while(ch<'0'||ch>'9')   t|=ch=='-',ch=gh();while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();return t?-x:x;}
    inline char getc(){char ch=gh();while(ch<'a'||ch>'z') ch=gh();return ch;}
    inline void write(int x){if(x < 0){putchar('-');x = -x;}if(x > 9){write(x / 10);}putchar((x % 10 + '0'));}
}
using namespace IO;
using namespace std;
const int Maxn = 300010;
int a[Maxn];
int n, m;
#define lowbit(x) x & (-x)
struct SumBit{
    int c[Maxn << 2]; 
    void Update(int i,int k){   
        while(i <= n){
            c[i] += k;
            i += lowbit(i);
        }
    }
    int Sum(int i){        
        int res = 0;
        while(i > 0){
            res += c[i];
            i -= lowbit(i);
        }
        return res;
    }
}t1;
struct MaxSegmentTree{
    int Tree[Maxn << 2], ma[Maxn << 2];
    #define ls(p) p << 1
    #define rs(p) p << 1 | 1
    void push_up(int p){
    	ma[p] = max(ma[ls(p)], ma[rs(p)]);
    }
    int build(int l, int r, int p){
        if(l == r){
            return ma[p] = a[l]; 
        }
        int mid = (l + r) >> 1;
        return ma[p] = max(build(l, mid, ls(p)), build(mid + 1, r, rs(p)));
    }
    void update(int l, int r, int p, int u, int val){
        if(l == r) {ma[p] = val; return;}
        int mid = (l + r) >> 1;
        if(u <= mid) update(l, mid, ls(p), u, val);
        else update(mid + 1, r, rs(p), u, val);
        push_up(p);
    }
    int query(int l, int r, int L, int R, int p){ // l,r 为查询
        if(L <= l && r <= R){
            return ma[p];
        }
        if(l > R || r < l) return 0;
        int mid = (l + r) >> 1;
        return max(query(l,mid,L,R,ls(p)), query(mid+1,r,L,R,rs(p)));
    } 
}t2;
struct MinSegmentTree{
    int Tree[Maxn << 2], mi[Maxn << 2];
    #define ls(p) p << 1
    #define rs(p) p << 1 | 1
    void push_up(int p){
    	mi[p] = min(mi[ls(p)], mi[rs(p)]);
    }
    int build(int l, int r, int p){
        if(l == r){
            return mi[p] = a[l]; 
        }
        int mid = (l + r) >> 1;
        return mi[p] = min(build(l, mid, ls(p)), build(mid + 1, r, rs(p)));
    }
    void update(int l, int r, int p, int u, int val){
        if(l == r) {mi[p] = val; return;}
        int mid = (l + r) >> 1;
        if(u <= mid) update(l, mid, ls(p), u, val);
        else update(mid + 1, r, rs(p), u, val);
        push_up(p);
    }
    int query(int l, int r, int L, int R, int p){ // l,r 为查询
        if(L <= l && r <= R){
            return mi[p];
        }
        if(l > R || r < l) return 0;
        int mid = (l + r) >> 1;
        return min(query(l,mid,L,R,ls(p)), query(mid+1,r,L,R,rs(p)));
    } 
}t3;
struct MaxBIT{
    int h[Maxn << 1];
    void update(int x){
        while(x <= n){
            h[x] = a[x];
            for(int i = 1; i < lowbit(x); i <<= 1)
                h[x]=max(h[x],h[x-i]);
            x += lowbit(x);
        }
        return ;
    }
    int query(int x, int y){
        int ans = 0;
        while (y >= x){
            ans = max(a[y], ans);
            y--;
            for (; y-lowbit(y) >= x; y -= lowbit(y))
                ans = max(h[y], ans);
    }
    return ans;
    }
}t4;
struct MinBIT{
    int h[Maxn << 1];
    void update(int x){
        while(x <= n){
            h[x] = a[x];
            for(int i = 1; i < lowbit(x); i <<= 1)
                h[x]=min(h[x],h[x-i]);
            x += lowbit(x);
        }
        return ;
    }
    int query(int x, int y){
        int ans = 114514111;
        while (y >= x){
            ans = min(a[y], ans);
            y--;
            for (; y-lowbit(y) >= x; y -= lowbit(y))
                ans = min(h[y], ans);
    }
    return ans;
    }
}t5;
signed main(){
//	freopen("P5278_1.in","r",stdin);
//	freopen("kk.out","w",stdout);
    int lst = 0;
    int m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        t1.Update(i,a[i]);
        t4.update(i);
        t5.update(i);
    }
    for(int i = 1; i <= m; i++){
        int op;
        cin >> op;
        if(op == 1){
            int x, y;
            cin >> x >> y;
            x ^= lst, y ^= lst;
            int p = a[x];
            a[x] = y; 
            t1.Update(x,y-p); 
            // t2.update(1,n,1,x,y); 
            // t3.update(1,n,1,x,y); 
            t4.update(x);
            t5.update(x);
        }
        else{
            int l, r, k;
            cin >> l >> r >> k;
            l ^= lst, r ^= lst, k ^= lst;
            int sum = t1.Sum(r) - t1.Sum(l-1);
            // int max = t2.query(l,r,1,n,1);
            // int min = t3.query(l,r,1,n,1);
            int max = t4.query(l,r);
            int min = t5.query(l,r);
        //    cout << sum << " " << max << " " << min << endl;
            if(max - min == k * (r - l) && sum == (max + min) * (r - l + 1) / 2 ) {
                cout << "Yes\n";
                lst++;
            }
            else cout << "No\n";
        }
    }
}

2023/9/12 19:45
加载中...