题目链接:传送门
题意:题意很简单,两种操作,一:区间每一个数或上x,二:求区间每个数或上x的总和。 (或 ' | ')
做法:最开始我想的就是单点更新,果断队友T了,然后队友用位来储存数字,然后延迟标记区间更新就过了,虽然找了很久bug。
///#include<bits/stdc++.h>
///#include<unordered_map>
///#include<unordered_set>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#include<new>
#include<vector>
#define MT(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const double E=2.718281828459;
const long long mod=1e9+7;
const int INF=0x3f3f3f3f;
int n,q,x,lazy[800000];
string u;
struct node
{
int pos[25];
node()
{
for(int i=0;i<=24;i++)
pos[i]=0;
}
}root[800000];
void upload(int sign)
{
for(int i=0;i<=22;i++)
root[sign].pos[i]=root[sign<<1].pos[i]+root[sign<<1|1].pos[i];
}
void download(int sign,int l,int r)
{
if(lazy[sign])
{
int mid=l+r>>1;
lazy[sign<<1]|=lazy[sign];
lazy[sign<<1|1]|=lazy[sign];
for(int i=0;i<=22;i++)
{
if(lazy[sign]>>i&1)
{
root[sign<<1].pos[i]=mid-l+1;
root[sign<<1|1].pos[i]=r-mid;
}
}
lazy[sign]=0;
}
}
void buildroot(int l,int r,int sign)
{
if(l==r)
{
scanf("%d",&x);
for(int i=0;i<=22;i++)
root[sign].pos[i]=x>>i&1;
return ;
}
int mid=l+r>>1;
buildroot(l,mid,sign<<1);
buildroot(mid+1,r,sign<<1|1);
upload(sign);
}
void updateroot(int l,int r,int sign,int a,int b,int c)
{
if(a==l&&r==b)
{
lazy[sign]|=c;
for(int i=0;i<=22;i++)
{
if(lazy[sign]>>i&1)
root[sign].pos[i]=r-l+1;
}
return ;
}
download(sign,l,r);
int mid=l+r>>1;
if(b<=mid)
updateroot(l,mid,sign<<1,a,b,c);
else if(a>mid)
updateroot(mid+1,r,sign<<1|1,a,b,c);
else
{
updateroot(l,mid,sign<<1,a,mid,c);
updateroot(mid+1,r,sign<<1|1,mid+1,b,c);
}
upload(sign);
}
ll findroot(int l,int r,int sign,int a,int b)
{
if(a==l&&r==b)
{
ll ans=0;
for(int i=0;i<=22;i++)
ans+=(root[sign].pos[i]*(1LL<<i));
return ans;
}
download(sign,l,r);
int mid=l+r>>1;
ll ans=0;
if(b<=mid)
ans+=findroot(l,mid,sign<<1,a,b);
else if(a>mid)
ans+=findroot(mid+1,r,sign<<1|1,a,b);
else
{
ans+=findroot(l,mid,sign<<1,a,mid);
ans+=findroot(mid+1,r,sign<<1|1,mid+1,b);
}
return ans;
}
int main()
{
MT(lazy,0);
scanf("%d %d",&n,&q);
buildroot(1,n,1);
while(q--)
{
cin>>u;
if(u=="SUM")
{
int a,b;
scanf("%d %d",&a,&b);
printf("%lld\n",findroot(1,n,1,a,b));
}
else
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
updateroot(1,n,1,a,b,c);
}
}
return 0;
}