现在的位置: 首页 > 综合 > 正文

CodeForces 121E Lucky Array (树状数组)

2014年11月07日 ⁄ 综合 ⁄ 共 2861字 ⁄ 字号 评论关闭
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;
}

抱歉!评论已关闭.