提交的代码已经添加快读,但是快读有一百多行为了美观我这里删了。
#include<bits/stdc++.h>
using namespace std;
int n,q,l,r,x,block[300010],num;
long long to[1000][100];
long long a[300010],Ad[1000];
bool flag[1000];
char op;
inline void add(int lef,int rig,int fixnum){
if(flag[block[lef]]){
for(int i=(block[lef]-1)*num+1;i<=min(n,block[lef]*num);i++)
a[i]=to[block[lef]][a[i]];
flag[block[lef]]=0;
}
for(int i=lef;i<=min(rig,block[lef]*num);i++)a[i]+=fixnum;
if(block[lef]!=block[rig]){
if(flag[block[rig]]){
for(int i=(block[rig]-1)*num+1;i<=min(n,block[rig]*num);i++)
a[i]=to[block[rig]][a[i]];
flag[block[rig]]=0;
}
for(int i=(block[rig]-1)*num+1;i<=rig;i++)a[i]+=fixnum;
}
for(int i=block[lef]+1;i<block[rig];i++){
if(flag[i])for(int j=0;j<=50;j++)to[i][j]+=fixnum;
else Ad[i]+=fixnum;
}
}
inline void pop(int lef,int rig){
if(flag[block[lef]]){
for(int i=(block[lef]-1)*num+1;i<=min(n,block[lef]*num);i++)
a[i]=to[block[lef]][a[i]];
flag[block[lef]]=0;
}
for(int i=lef;i<=min(rig,block[lef]*num);i++)a[i]=__builtin_popcountll(a[i]);
if(block[lef]!=block[rig]){
if(flag[block[rig]]){
for(int i=(block[rig]-1)*num+1;i<=min(n,block[rig]*num);i++)
a[i]=to[block[rig]][a[i]];
flag[block[rig]]=0;
}
for(int i=(block[rig]-1)*num+1;i<=rig;i++)a[i]=__builtin_popcountll(a[i]);
}
for(int i=block[lef]+1;i<block[rig];i++){
if(flag[i])for(int j=0;j<=50;j++)to[i][j]=__builtin_popcountll(to[i][j]);
else{
for(int j=0;j<=50;j++)to[i][j]=j;flag[i]=1;
for(int j=(i-1)*num+1;j<=min(n,i*num);j++)
a[j]=__builtin_popcountll(a[j]+Ad[i]);
Ad[i]=0;
}
}
}
inline long long query(int x){
if(flag[block[x]])return to[block[x]][a[x]];
else return a[x]+Ad[block[x]];
}
int main(){
cin>>n>>q;num=sqrt(n*50ll);
for(int i=1;i<=n;i++){
cin>>a[i];
block[i]=(i-1)/num+1;
}
while(q--){
cin>>op;
switch(op){
case 'A':
cin>>l>>r>>x;
add(l,r,x);
break;
case 'P':
cin>>l>>r;
pop(l,r);
break;
case 'J':
cin>>x;
cout<<query(x)<<"\n";
break;
}
}
}