题意:给定n个数,若某一个数完全由4和7组成,则为luck number,问一个区间有多少个luck number(且全部数小于10四次方)
题解:先开一个数组记录luck number 是则为1,其他为0,用该数组直接判是否luck number。按原来的顺序建立树状数组,add就先判断哪个点是不是luck number,若是则这个位置的树状数组-1,然后add完之后判断是否luck number,是的话则这个位置树状数组+1,若要count就sum(y)-sum(x-1)就是结果.
#include<stdio.h>
#include<string.h>
int mark[10005],tree[100005],a[100005];
int n,m;
void init()
{
mark[4]=mark[7]=mark[44]=mark[47]=1;
mark[74]=mark[77]=mark[444]=mark[447]=1;
mark[474]=mark[477]=mark[744]=mark[747]=1;
mark[774]=mark[777]=mark[4444]=mark[4447]=1;
mark[4474]=mark[4477]=mark[4744]=mark[4747]=1;
mark[4774]=mark[4777]=mark[7444]=mark[7447]=1;
mark[7474]=mark[7477]=mark[7744]=mark[7747]=1;
mark[7774]=mark[7777]=1;
}
int low_bit(int x)
{
return x&(-x);
}
void add(int x,int y)
{
while(x<=n)
{
tree[x]+=y;
x+=low_bit(x);
}
}
int sum(int x)
{
int temp=0;
while(x>0)
{
temp+=tree[x];
x-=low_bit(x);
}
return temp;
}
int main()
{
int i,j,x,y,z;
char s[10];
memset(mark,0,sizeof(mark));
init();
while(scanf("%d%d",&n,&m)>0)
{
for(i=0;i<=n;i++) tree[i]=0;
for(i=1;i<=n;i++)
{
scanf("%d",a+i);
if(mark[a[i]]) add(i,1);
}
for(j=0;j<m;j++)
{
scanf("%s%d%d",s,&x,&y);
if(s[0]=='c') printf("%d\n",sum(y)-sum(x-1));
else
{
scanf("%d",&z);
if(z==0) continue;
for(i=x;i<=y;i++)
{
if(mark[a[i]]) add(i,-1);
a[i]+=z;
if(mark[a[i]]) add(i,1);
}
}
}
}
return 0;
}