【GDKOI 2016】魔法少女Code&&Details
Details
xの2進法の現在のi番目のビットが1であるか0であるかを判断するx&(1<
Code
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define ll long long
const int maxn=100007;
const int mo=100000007;
struct node{
int l[2],r[2],zong;
ll sum[2];
}t[10][maxn*3],ans;
using namespace std;
int i,j,k,l,n,m;
ll ans1;
char ch;
int a[maxn],mi[100];
inline int read(int n)
{
char ch=getchar();
while((ch!='-')&&((ch<'0')||(ch>'9')))ch=getchar();
int q=0,w=1;if(ch=='-')w=-1,ch=getchar();
while(ch>='0' && ch<='9'){q=q*10+ch-48;ch=getchar();}n=q*w;return n;
}
inline void merge(node &x,int lei,int xx){
node y=t[lei][xx*2],z=t[lei][xx*2+1];
x.zong=y.zong^z.zong;
x.l[0]=(y.l[0]+z.l[y.zong]+1-y.zong)%mo;
x.r[0]=(z.r[0]+y.r[z.zong]+1-z.zong)%mo;
x.l[1]=(y.l[1]+y.zong+z.l[1-y.zong])%mo;
x.r[1]=(z.r[1]+z.zong+y.r[1-z.zong])%mo;
x.sum[1]=(y.sum[1]+z.sum[1]+y.r[0]*z.l[1]+y.r[1]*z.l[0]+y.r[1]+z.l[1])%mo;
}
inline void merge1(node &x,node y,node z){
x.zong=y.zong^z.zong;
x.l[0]=(y.l[0]+z.l[y.zong]+1-y.zong)%mo;
x.r[0]=(z.r[0]+y.r[z.zong]+1-z.zong)%mo;
x.l[1]=(y.l[1]+y.zong+z.l[1-y.zong])%mo;
x.r[1]=(z.r[1]+z.zong+y.r[1-z.zong])%mo;
x.sum[1]=(y.sum[1]+z.sum[1]+y.r[0]*z.l[1]+y.r[1]*z.l[0]+y.r[1]+z.l[1])%mo;
}
inline void build(int lei,int x,int l,int r){
int mid=(l+r)/2;
if(l==r){
t[lei][x].zong=((a[l]&mi[lei])>0);
}
else{
build(lei,x*2,l,mid);
build(lei,x*2+1,mid+1,r);
merge(t[lei][x],lei,x);
}
}
inline void change(int lei,int x,int l,int r,int y){
if(l==r){
t[lei][x].zong=((a[y]&mi[lei])>0);
}
else{
int mid=(l+r)/2;
if(y<=mid) change(lei,x*2,l,mid,y);
else change(lei,x*2+1,mid+1,r,y);
merge(t[lei][x],lei,x);
}
}
void find(int lei,int x,int l,int r,int y,int z){
if(l==y&&r==z){
if (ans.zong<0) ans=t[lei][x];else
merge1(ans,ans,t[lei][x]);
}
else{
int mid=(l+r)/2;
if(z<=mid)find(lei,x*2,l,mid,y,z);
else if(y>mid)find(lei,x*2+1,mid+1,r,y,z);
else{
find(lei,x*2,l,mid,y,mid);
find(lei,x*2+1,mid+1,r,mid+1,z);
}
}
}
int main(){
scanf("%d",&n);
fo(i,1,n){
scanf("%d",&a[i]);
}
fo(j,0,9)mi[j]=(1<0,9){
build(j,1,1,n);
}
scanf("%d",&m);
fo(i,1,m){
// scanf("%s%d%d",ch,&k,&l);
ch=getchar();
while(ch!='Q'&&ch!='M')ch=getchar();
k=read(k);
l=read(l);
ans1=0;
if(ch=='Q'){
fo(j,0,9){
ans.zong=-1;
find(j,1,1,n,k,l);
ans1=(ans1+(ans.r[1]+ans.l[1]+ans.sum[1]+ans.zong)*mi[j])%mo;
}
printf("%lld
",ans1);
}
else{
a[k]=l;
fo(j,0,9){
change(j,1,1,n,k);
}
}
}
}