[jzoj4711]【NOIP2016提高A组模拟8.17】Binary

来源:互联网 发布:mac过滤是什么意思 编辑:程序博客网 时间:2024/05/23 19:16

Description

这里写图片描述

Solution

拆位考虑

设当前考虑第 i 位

2i(a+x)%2i+1<2i+1

2ixa<2i+1x

可以用树状数组解决

每次每位 查询

[2ix,2i+1x)

树状数组解决

Code

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define fo(i,x,y) for (ll pq = (y),i = (x);i <= pq;++ i)#define fd(i,x,y) for (ll pq = (y),i = (x);i >= pq;-- i)#define oo 2139062143using namespace std;typedef double db;typedef long long ll;ll lowbit(ll x) {return((x)&(-x));}ll min(ll x,ll y){return (x>y)?(y):(x);}ll max(ll x,ll y){return (x>y)?(x):(y);}ll er(ll x){    return(1<<(x));}const ll N=100100,MX=(1<<21)-1;ll n,q;ll a[N];ll opt,x,y;ll t[22][MX];void add(ll pos,ll x,ll v){    ++x;    while(x<=MX)    {        t[pos][x]+=v;        x+=lowbit(x);    }}ll query(ll pos,ll x){    ++x;    x=min(x,MX);    ll rt=0;    while(x>0)    {        rt+=t[pos][x];        x-=lowbit(x);    }       return rt;}int main(){    scanf("%lld%d",&n,&q);    fo(i,1,n)    {        scanf("%lld",&a[i]);        fo(l,0,20) add(l,a[i]&(er(l+1)-1),1);    }    while(q--)    {        scanf("%lld%lld%lld",&opt,&x,&y);        if(opt==1)        {            fo(l,0,20) add(l,a[x]&(er(l+1)-1),-1),add(l,y&(er(l+1)-1),1);            a[x]=y;        }        else        if(opt==2)        {            ll ans=0;            fo(l,0,20)            if(y&er(l))            {                ll tmp=0;                tmp+=(query(l,er(l+1)-1-(x&(er(l+1)-1)))-query(l,er(l)-1-(x&(er(l+1)-1))));                tmp+=query(l,er(l+1)+er(l+1)-1-(x&(er(l+1)-1)))-query(l,er(l+1)+er(l)-1-(x&(er(l+1)-1)));                ans+=tmp*er(l);            }            printf("%lld\n",ans);        }    }    return 0;}
原创粉丝点击