CodeForces 121E Lucky Array (树状数组)

E. Lucky Array
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.

Petya has an array consisting of n numbers. He wants to perform m operations of two types:

  • add l r d — add an integer d to all elements whose indexes belong to the interval from l to r, inclusive (1 ≤ l ≤ r ≤ n, 1 ≤ d ≤ 104);
  • count l r — find and print on the screen how many lucky numbers there are among elements with indexes that belong to the interval from l to r inclusive (1 ≤ l ≤ r ≤ n). Each lucky number should be counted as many times as it appears in the interval.

Petya has a list of all operations. The operations are such that after all additions the array won't have numbers that would exceed 104. Help Petya write a program that would perform these operations.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 105) — the number of numbers in the array and the number of operations correspondingly. The second line contains n positive integers, none of which exceeds 104 — those are the array numbers. Next m lines contain operations, one per line. They correspond to the description given in the statement.

It is guaranteed that after all operations are fulfilled each number in the array will not exceed 104.

Output

For each operation of the second type print the single number on the single line — the number of lucky numbers in the corresponding interval.

Sample test(s)
Input
3 6
2 3 4
count 1 3
count 1 2
add 1 3 2
count 1 3
add 2 3 3
count 1 3
Output
1
0
1
1
Input
4 5
4 4 4 4
count 1 4
add 1 4 3
count 1 4
add 2 3 40
count 1 4
Output
4
4
4
Note

In the first sample after the first addition the array will look in the following manner:

4 5 6

After the second addition:

4 8 9

The second sample after the first addition:

7 7 7 7

After the second addition:

7 47 47 7


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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值