CodeForces E. Lucky Array 幸运数列

Posted 心之所向 素履以往

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces E. Lucky Array 幸运数列相关的知识,希望对你有一定的参考价值。

                                            CodeForces    E. Lucky Array  幸运数列 

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.

Examples
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

 

中文题面 :http://cogs.pro/cogs/problem/problem.php?pid=1922

 

 

先找出小于100000的所有幸运数 暴力修改 

CF上时限4s 完全没问题 

但是COGS上时限2s 就被卡吵了

 

技术分享
 1 /*
 2     线段树光荣T了5个点
 3     还是树状数组吧 
 4     但是CF上过了 只用了3.4s 
 5 */
 6 #include <ctype.h>
 7 #include <cstdio>
 8 
 9 const int MAXN=100010;
10 
11 int n,m,x;
12 
13 int a[MAXN],b[50]={0,4,7,44,47,74,77,444,447,474,477,744,747,774,777,4444,4447,4474,4477,4744,4747,4774,4777,7444,7447,7474,7477,7744,7747,7774,7777,};
14 
15 struct node {
16     int l,r;
17     int sum;
18 };
19 node t[MAXN<<2];
20 
21 char s[20];
22 
23 bool vis[MAXN];
24 
25 inline void read(int&x) {
26     int f=1;register char c=getchar();
27     for(x=0;!isdigit(c);c==-&&(f=-1),c=getchar());
28     for(;isdigit(c);x=x*10+c-48,c=getchar());
29     x=x*f;
30 }
31 
32 void build_tree(int now,int l,int r) {
33     t[now].l=l,t[now].r=r;
34     if(l==r) {
35         read(a[l]);
36         if(vis[a[l]]) ++t[now].sum;
37         return;
38     }
39     int mid=(l+r)>>1;
40     build_tree(now<<1,l,mid);
41     build_tree(now<<1|1,mid+1,r);
42     t[now].sum=t[now<<1].sum+t[now<<1|1].sum;
43 }
44 
45 void modify(int now,int pos,int v) {
46     if(t[now].l==t[now].r) {
47         t[now].sum+=v;
48         return;
49     }
50     int mid=(t[now].l+t[now].r)>>1;
51     if(pos<=mid) modify(now<<1,pos,v);
52     else modify(now<<1|1,pos,v);
53     t[now].sum=t[now<<1].sum+t[now<<1|1].sum;
54 }
55 
56 int query(int now,int l,int r) {
57     if(l<=t[now].l&&r>=t[now].r) return t[now].sum;
58     int tot=0;
59     int mid=(t[now].l+t[now].r)>>1;
60     if(l<=mid) tot+=query(now<<1,l,r);
61     if(r>mid) tot+=query(now<<1|1,l,r);
62     return tot;
63 }
64 
65 int hh() {
66 //    freopen("cf121e.in","r",stdin);
67 //    freopen("cf121e.out","w",stdout);
68     int x,y,v;
69     read(n);read(m);
70     for(int i=1;i<=30;++i) vis[b[i]]=true;
71     build_tree(1,1,n);
72     for(int i=1;i<=m;++i) {
73         scanf("%s",s);
74         if(s[0]==c) {
75             read(x);read(y);
76             int t=query(1,x,y);
77             printf("%d\n",t);
78         }
79         else {
80             read(x);read(y);read(v);
81             for(int i=x;i<=y;++i) {
82                 int k=0;
83                 if(vis[a[i]]) --k;
84                 a[i]+=v;
85                 if(vis[a[i]]) ++k;
86                 if(k) modify(1,i,k);
87             }
88         }
89     }
90     return 0;
91 } 
92 
93 int sb=hh();
94 int main() {;}
线段树代码
技术分享
 1 /*
 2     树状数组T了1个点
 3     呜呜呜 -绝望- 
 4     CF上竟然过了 用了2.4s 
 5 */
 6 #include <ctype.h>
 7 #include <cstdio>
 8 
 9 #define lowbit(x) x&(-x)
10 
11 const int MAXN=100010;
12 
13 int n,m,x;
14 
15 int a[MAXN],t[MAXN],b[50]={0,4,7,44,47,74,77,444,447,474,477,744,747,774,777,4444,4447,4474,4477,4744,4747,4774,4777,7444,7447,7474,7477,7744,7747,7774,7777,};
16 
17 char s[20];
18 
19 bool vis[MAXN];
20 
21 inline void read(int&x) {
22     int f=1;register char c=getchar();
23     for(x=0;!isdigit(c);c==-&&(f=-1),c=getchar());
24     for(;isdigit(c);x=x*10+c-48,c=getchar());
25     x=x*f;
26 }
27 
28 inline void add(int x,int v) {
29     for(int i=x;i<=n;i+=lowbit(i))
30       t[i]+=v;
31 }
32 
33 inline int query(int x) {
34     int tot=0;
35     for(int i=x;i;i-=lowbit(i)) tot+=t[i];
36     return tot;
37 }
38 
39 int hh() {
40 //    freopen("cf121e.in","r",stdin);
41 //    freopen("cf121e.out","w",stdout);
42     int x,y,z;
43     read(n);read(m);
44     for(int i=1;i<=30;++i) vis[b[i]]=true;
45     for(int i=1;i<=n;++i) {
46         read(a[i]);
47         if(vis[a[i]]) add(i,1);
48     }
49     for(int i=1;i<=m;++i) {
50         scanf("%s",s);
51         read(x);read(y);
52         if(s[0]==a) {
53             read(z);
54             for(int i=x;i<=y;++i) {
55                 int k=0;
56                 if(vis[a[i]]) --k;
57                 a[i]+=z;
58                 if(vis[a[i]]) ++k;
59                 if(k) add(i,k);
60             }
61         }
62         else printf("%d\n",query(y)-query(x-1));
63     }
64     return 0;
65 }
66 
67 int sb=hh();
68 int main() {;}
树状数组代码

 

以上是关于CodeForces E. Lucky Array 幸运数列的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces - 808A Lucky Year

CodeForces - 808A Lucky Year

『题解』Codeforces121A Lucky Sum

Lucky Numbers (easy) CodeForces - 96B

@codeforces - 1096G@ Lucky Tickets

codeforces 110E Lucky Tree