And RMQ 势能线段树-用剪枝+单点修改实现区间修改

https://codeforces.com/gym/103107/problem/A

A. And RMQ

time limit per test
3 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

You are given a sequence consisting of NN integers {ai}{ai}. There will be mm different events.

 

  • AND l r vAND l r v – for all elements ai (lir)ai (l≤i≤r), change aiai to ai & vai & v, where && means bitwise AND

     

  • UPD x vUPD x v – change axax to vv

     

  • QUE l rQUE l r – ask for the maximum value of aiai where lirl≤i≤r

Please write a program to support these events efficiently.

分析:

要是某个位置用&操作不会改变它的值了,说明v中0的位置在子节点中已经全部变成0了。

设一个lazy(严格来说不是懒标记,因为不会向下传递而是向上传递)表示子节点哪些位置还没变成0

如果这些位置都不在 v 的0的位置的范围内,就不需要向下传递。

//-------------------------代码----------------------------

#define int ll
const int N = 4e5+10;
int n,m;
int a[N];
struct node {
    int l,r;
    int mx;
    bitset<31>lazy;
}tr[N << 2]; 

void push_up(int u) {
    tr[u].mx = max(tr[u<<1].mx,tr[u<<1|1].mx);
    tr[u].lazy = tr[u<<1].lazy | tr[ur].lazy;
}

void build(int u,int l,int r) {
    tr[u] = {l,r};
    if(l == r) {
        tr[u].mx = a[l];
        tr[u].lazy = a[l];
        return;
    }
    build(ul,l,tr_mid);build(ur,tr_mid+1,r);
    push_up(u);
} 

void upt_and(int u,int l,int r,int v) {
    bitset<31> tmp(v);
    bitset<31> rtmp(v);
    rtmp.flip();
    if((rtmp & tr[u].lazy) == 0) return;
    if(tr[u].l == tr[u].r) {
        tr[u].mx = tr[u].mx & v;
        tr[u].lazy &= tmp;
        return;
    }
    if(l <= tr_mid) upt_and(ul,l,r,v);
    if(tr_mid < r ) upt_and(ur,l,r,v);
    push_up(u);
}

void upt(int u,int x,int v) {
    if(tr[u].l > x || tr[u].r < x) return ;
    if(tr[u].l == tr[u].r) {
        tr[u].mx = v;
        tr[u].lazy = bitset<31>(v);
        return;
    }
    if(x <= tr_mid)upt(ul,x,v);
    else upt(ur,x,v);
    push_up(u);
}

ll query(int u,int l,int r) {
    if(l <= tr[u].l && tr[u].r <= r) {
        return tr[u].mx;
    }
    if(tr[u].l > r || tr[u].r < l) return 0;
    return max(query(ul,l,r),query(ur,l,r));
}

void solve()
{
    cin>>n>>m;
    fo(i,1,n) cin>>a[i];
    build(1, 1, n);
    while (m--) {
        string op; cin >> op;
        if (op == "AND") {
            int l, r, v; cin >> l >> r >> v;
            upt_and(1, l, r, v);
        }
        else if (op == "UPD") {
            int x, v; cin >> x >> v;
            upt(1, x, v);
        }
        else {
            int l, r; cin >> l >> r;
            cout << query(1, l, r) << endl;
        }
    }
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-09-19 14:48  er007  阅读(24)  评论(0编辑  收藏  举报