题意:给定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; }