5.16(未完成)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5;
typedef pair<int,int>PII;
struct G{
int l,r;
int cnt[64];
string a;
vector<int>v;
int sum;
};
G tr[N];
int p[N];
void pushup(G &a,G &b,G &c){
for(int i=0;i<=60;i++)a.cnt[i]=b.cnt[i]+c.cnt[i];
}
void pushup(int v)
{
pushup(tr[v],tr[v<<1],tr[v<<1|1]);
}
void add(int v,int c,char t)
{

if(t=='1'){
int k=tr[v].r-tr[v].l+1;
int j,q;
if(tr[v].l&1)j=(k+1)/2,q=k/2;
else j=k/2,q=(k+1)/2;
for(int i=0;i<=60;i++)-
tr[v].cnt[i]=(c>>i&1)?q:j;
}
else if(t=='&'){
int t=tr[v].l-tr[v].r+1;
for(int i=0;i<=60;i++)
tr[v].cnt[i]=((c>>i&1)?min(tr[v].cnt[i],t):0);
}
else if(t=='|')
{
for(int i=0;i<=60;i++)
tr[v].cnt[i]=((c>>i&1)?t:tr[v].cnt[i],t);
}
else{
for(int i=0;i<=60;i++)
{
int t=tr[v].l-tr[v].r+1;
if(c>>i&1)tr[v].cnt[i]=t-tr[v].cnt[i];
}
}
tr[v].a+=t;
return ;
}
void pushdown(int v)
{
string a=tr[v].a;
for(int i=0;i<a.size();i++)
{
char t=a[i];
int c=tr[v].v[i];
add(v<<1,c,t);
add(v<<1|1,c,t);
}
tr[v].a.clear();
tr[v].v.clear();
}
void build(int v,int l,int r)
{
tr[v]={l,r};
if(l==r)
{
for(int i=0;i<=60;i++)tr[v].cnt[i]=(p[l]>>i&1) xor (l>>i&1);
//cout<<tr[v].cnt[i];
//cout<<"\n";
return ;
}
int mid=l+r>>1;
build(v<<1,l,mid);
build(v<<1|1,mid+1,r);
pushup(v);
}
G quert(int v,int l,int r)
{
if(tr[v].l>=l&&tr[v].r<=r)return tr[v];
pushdown(v);
G sum,ans,an;
for(int i=0;i<=60;i++)ans.cnt[i]=an.cnt[i]=0;
int mid=tr[v].l+tr[v].r>>1;
if(l<=mid)ans=quert(v<<1,l,r);
if(mid<r)an=quert(v<<1|1,l,r);
pushup(v);
pushup(sum,ans,an);
return sum;
}
void mul(int v,int l,int r,int c,char t) {
if (tr[v].l >= l && tr[v].r <= r) {
if (t == '1') {
int j,q;
int k = tr[v].r - tr[v].l + 1;
if(tr[v].l&1)j=k/2,q=(k+1)/2;
else j=(k+1)/2,q=k/2;
for (int i = 0; i <= 60; i++)
tr[v].cnt[i] = (1-(c >> i & 1))?q:j;
} else if (t == '&') {
int t = tr[v].l - tr[v].r + 1;
for (int i = 0; i <= 60; i++)
tr[v].cnt[i] = ((c >> i & 1) ? min(tr[v].cnt[i], t) : 0);
} else if (t == '|') {
} else {
int t = tr[v].l - tr[v].r + 1;
for (int i = 0; i <= 60; i++) {
if (c >> i & 1)tr[v].cnt[i] = t - tr[v].cnt[i];

}
tr[v].a += t;
tr[v].v.push_back(c);
return;
}
pushdown(v);
int mid = tr[v].l + tr[v].r >> 1;
if (mid >= l)mul(v << 1, l, r, c, t);
if (mid < r)mul(v << 1 | 1, l, r, c, t);
pushup(v);
}
}
signed main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>p[i];
build(1,1,n);
while(m--)
{
int a,b;
cin>>a;
if(a==1){
int l,r;
cin>>l>>r;
G k=quert(1,l,r);
int sum=0,s=r-l+1;
for(int i=60;i>=0;i--)sum=sum*2+(k.cnt[i]);
// cout<<"\n";
cout<<sum<<"\n";
}
else if(a==2){
int l,r,t;
cin>>l>>r>>t;
mul(1,l,r,t,'1');
}
else {
int l,r,t;
char c;
cin>>l>>r>>t>>c;
mul(1,l,r,t,c);
}
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值