模拟赛时写的代码,22pts,实在找不出问题了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=3e5+5,M=64,mod=998244353;
ll t,n,q,a[N];
struct node{
ll A,B,p;
short f[M];
}tree[N<<2];
#define lc k<<1
#define rc k<<1|1
#define ls lc,l,mid
#define rs rc,mid+1,r
void pushdown(int k){
if(!tree[k].p){
tree[lc].B+=tree[k].B;
tree[rc].B+=tree[k].B;
tree[k].A=tree[k].B=tree[k].p=0;
for(int i=0;i<M;i++)
tree[k].f[i]=0;
}
else{
if(!tree[lc].p){
tree[lc].A=tree[lc].B+tree[k].A;
tree[lc].B=tree[k].B;
tree[lc].p=1;
for(int i=0;i<M;i++)
tree[lc].f[i]=tree[k].f[i];
}
else{
for(int i=0;i<M;i++)
tree[lc].f[i]=tree[k].f[__builtin_popcount(tree[lc].f[i]+tree[lc].B+tree[k].A)];
tree[lc].B=tree[k].B;
}
if(!tree[rc].p){
tree[rc].A=tree[rc].B+tree[k].A;
tree[rc].B=tree[k].B;
tree[rc].p=1;
for(int i=0;i<M;i++)
tree[rc].f[i]=tree[k].f[i];
}
else{
for(int i=0;i<M;i++)
tree[rc].f[i]=tree[k].f[__builtin_popcount(tree[rc].f[i]+tree[rc].B+tree[k].A)];
tree[rc].B=tree[k].B;
}
tree[k].A=tree[k].B=tree[k].p=0;
for(int i=0;i<M;i++)
tree[k].f[i]=0;
}
}
void change1(int k,int l,int r,int x,int y,ll d){
if(x<=l&&r<=y){
tree[k].B+=d;
return ;
}
int mid=l+r>>1;
pushdown(k);
if(x<=mid) change1(ls,x,y,d);
if(mid<y) change1(rs,x,y,d);
}
void change2(int k,int l,int r,int x,int y){
if(x<=l&&r<=y){
if(!tree[k].p){
tree[k].A=tree[k].B;
tree[k].B=0;
tree[k].p=1;
for(int i=0;i<M;i++)
tree[k].f[i]=i;
}
else{
for(int i=0;i<M;i++)
tree[k].f[i]=__builtin_popcount(tree[k].f[i]+tree[k].B);
tree[k].B=0;
}
return ;
}
int mid=l+r>>1;
pushdown(k);
if(x<=mid) change2(ls,x,y);
if(mid<y) change2(rs,x,y);
}
ll query(int k,int l,int r,int x){
if(l==r){
if(!tree[k].p)
return tree[k].B+a[l];
return tree[k].B+tree[k].f[__builtin_popcount(a[l]+tree[k].A)];
}
int mid=l+r>>1;
pushdown(k);
if(x<=mid) return query(ls,x);
else return query(rs,x);
}
int main(){
// freopen("dream.in","r",stdin);
// freopen("dream.out","w",stdout);
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
char op[15];
ll x,y,v;
while(q--){
scanf("%s",op+1);
if(op[1]=='A'){
scanf("%lld%lld%lld",&x,&y,&v);
change1(1,1,n,x,y,v);
}
else
if(op[1]=='P'){
scanf("%lld%lld",&x,&y);
change2(1,1,n,x,y);
}
else
if(op[1]=='J'){
scanf("%lld",&x);
printf("%lld\n",query(1,1,n,x));
}
}
return 0;
}