题解 P4641 【[BJWC2008]序列】
题意:
给你一个序列,支持全局加及查询二进制某位为
设序列中的数的值域为
注意到操作都是全局的,所以序列中的数可以开桶来存,全局加也可以用标记解决。
对于查询,需要计入答案的数的区间是 加个指令集就可以过了,代码。
通过观察发现其答案只与加上的数的和的后 可以卡到最优解。
AC代码:(
#include<bits/stdc++.h>
int n,m,a2;
char c;
unsigned short p,x;
int sum[131088],cnt[131088],ans[17][65537];
bool vis[17][65537];
int main()
{
register long long anss=0;
register unsigned short p=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)scanf("%d",&a2),++cnt[a2],++cnt[a2+65536];
sum[0]=cnt[0];
for(int i=1;i<131088;i++)sum[i]=sum[i-1]+cnt[i];
while(m--)
{
scanf("%s%d",&c,&x);
if(c=='A')p+=x;
else
{
if(vis[x][p&((2<<x)-1)])anss+=ans[x][p&((2<<x)-1)];
else
{
register int ansa=0;
for(register int i=(2<<x)-1;i<65536;i+=2<<x)ansa+=sum[65536-p+i]-sum[65536-p+i-(1<<x)];
vis[x][p&((2<<x)-1)]=1,anss+=(ans[x][p&((2<<x)-1)]=ansa);
}
}
}
printf("%lld",anss);
return 0;
}