And RMQ 势能线段树-用剪枝+单点修改实现区间修改
https://codeforces.com/gym/103107/problem/A
A. And RMQ
time limit per test
3 secondsmemory limit per test
512 megabytesinput
standard inputoutput
standard outputYou 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 (l≤i≤r)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 l≤i≤rl≤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; } /*样例区 */ //------------------------------------------------------------