• Sonya and Bitwise OR CodeForces


    大意: 给定序列$a$, 给定整数$x$. 两种操作(1)单点修改 (2)给定区间$[l,r]$,求有多少子区间满足位或和不少于$x$.

    假设不带修改. 固定右端点, 合法区间关于左端点单调的. 可以预处理出最近的合法的左端点位置.那么每次询问答案就为$sumlimits_{substack{pre[i]ge l\ l le ile r}}(pre[i]-l+1)$. 用二维数点的方法处理即可.

    带修改的话, 关键是要注意到或和最多改变$20$次, 线段树记录下来改变的位置, 暴力合并即可.

    #include <iostream>
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <math.h>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <string.h>
    #include <bitset>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define PER(i,a,n) for(int i=n;i>=a;--i)
    #define hr putchar(10)
    #define pb push_back
    #define lc (o<<1)
    #define rc (lc|1)
    #define mid ((l+r)>>1)
    #define ls lc,l,mid
    #define rs rc,mid+1,r
    #define x first
    #define y second
    #define io std::ios::sync_with_stdio(false)
    #define endl '
    '
    #define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;})
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    
    const int N = 1e5+10;
    int n,m,X,a[N];
    struct _ {
    	int lnum,rnum,x,L,R;
    	ll ans;
    	pii l[22],r[22];
    	_ () {}
    	_ (int lnum,int rnum,int x,int L,int R,ll ans):lnum(lnum),rnum(rnum),x(x),L(L),R(R),ans(ans) {}
    	_ (int pos, int val) {
    		L=R=l[1].y=r[1].y=pos;
    		l[1].x=r[1].x=x=val;
    		ans=(val<X);
    		lnum=rnum=1;
    	}
    	_ operator + (const _& rhs) const {
    		_ ret(lnum,rhs.rnum,x|rhs.x,L,rhs.R,ans+rhs.ans);
    		memcpy(ret.l,l,sizeof l);
    		memcpy(ret.r,rhs.r,sizeof r);
    		for (int i=rnum,j=0; i; --i) {
    			while (j<rhs.lnum&&(r[i].x|rhs.l[j+1].x)<X) ++j;
    			ret.ans += (ll)(r[i].y-(i<rnum?r[i+1].y:L-1))*((j<rhs.lnum?rhs.l[j+1].y:rhs.R+1)-rhs.L);
    		}
    		REP(i,1,rhs.lnum) if ((rhs.l[i].x|x)!=ret.l[ret.lnum].x) { 
    			(ret.l[++ret.lnum]=rhs.l[i]).x |= x;
    		}
    		REP(i,1,rnum) if ((r[i].x|rhs.x)!=ret.r[ret.rnum].x) { 
    			(ret.r[++ret.rnum]=r[i]).x |= rhs.x;
    		}
    		return ret;
    	}
    } tr[N<<2];
    void build(int o, int l, int r) {
    	if (l==r) tr[o]=_(l,a[l]);
    	else build(ls),build(rs),tr[o]=tr[lc]+tr[rc];
    }
    void update(int o, int l, int r, int x, int v) {
    	if (l==r) tr[o]=_(x,v);
    	else {
    		mid>=x?update(ls,x,v):update(rs,x,v);
    		tr[o]=tr[lc]+tr[rc];
    	}
    }
    _ query(int o, int l, int r, int ql, int qr) {
    	if (ql<=l&&r<=qr) return tr[o];
    	if (mid>=qr) return query(ls,ql,qr);
    	if (mid<ql) return query(rs,ql,qr);
    	return query(ls,ql,qr)+query(rs,ql,qr);
    }
    int main() {
    	scanf("%d%d%d", &n, &m, &X);
    	REP(i,1,n) scanf("%d", a+i);
    	build(1,1,n);
    	while (m--) {
    		int op,x,y;
    		scanf("%d%d%d", &op, &x, &y);
    		if (op==1) update(1,1,n,x,y);
    		else printf("%lld
    ",(y-x+1ll)*(y-x+2)/2-query(1,1,n,x,y).ans);
    	}
    }
    
  • 相关阅读:
    C# WinForm 关于窗体最大化时的是否全屏效果与是否遮盖任务栏
    C# winform 无边框 窗体的拖动
    lenovo 联想笔记本ideapad 320c-15改装win7问题
    解决WIN7第一次开机冷启动QQ未响应的办法
    WIN10X64_LTSB2016极限精简版by双心
    RAMOS和SSD对比
    联想IDEAPAD 320C-15笔记本显卡驱动问题
    WIN7以上系统安装VB6的解决办法,附上个批处理。
    吐槽下银联1分钱乘公交
    QQ聊天框变成方框口口口口的解决办法
  • 原文地址:https://www.cnblogs.com/uid001/p/11178047.html
Copyright © 2020-2023  润新知