Time Limit: 10 Sec, Memory Limit: 256 MB
Petya loves lucky numbers. Everybodyknows that lucky numbers are positive integers whose decimal representationcontains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are luckyand 5, 17, 467 are not. Petya has an array consisting of n numbers. He wants toperform m operations of two types: add l r d — add an integer d to all elementswhose indexes belong to the interval from l to r, inclusive(1 ≤ l ≤ r ≤ n, 1 ≤ d ≤ 10^4); count l r — find and print on the screen howmany lucky numbers there are among elements with indexes that belong to theinterval from l to r inclusive (1 ≤ l ≤ r ≤ n). Each lucky number should becounted as many times as it appears in the interval. Petya has a list of alloperations. The operations are such that after all additions the array won'thave numbers that would exceed 10^4. Help Petya write a program that wouldperform these operations.
The first line contains two integers nand m (1 ≤ n ≤ 106, 1 ≤ m ≤ 104) — the number of numbersin the array and the number of operations correspondingly. The second linecontains n positive integers, none of which exceeds 104 — those arethe array numbers. Next m lines contain operations, one per line. Theycorrespond to the description given in the statement. It is guaranteed thatafter all operations are fulfilled each number in the array will not exceed 104.
For each operation of the second typeprint the single number on the single line — the number of lucky numbers in thecorresponding interval.
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
1
0
1
1
思路:
这题一开始就想到分块做了,但是从来没写过,最后还是放弃了。其实这题关键信息是lucky数不超过10000,所以就能够暴力一个块的lucky数了。
AC代码:
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<cmath> #include<ctime> #include<cstdlib> #include<queue> #include<vector> #include<set> using namespace std; const int T=20100; const int N=2000; #define inf 0x3f3f3f3fL #define mod 1000000000 #define lson (rt<<1) #define rson (rt<<1|1) typedef long long ll; typedef unsigned long long ULL; int sz; int lucky[T],delta[N],numCnt[N][T],num[1111111]; queue<int> q; int main() { #ifdef zsc freopen("input.txt","r",stdin); #endif int n,m,i,j,k,lky,L,R,d; q.push(4);q.push(7); lky = 0; while(!q.empty()) { ll cur = q.front();q.pop(); lucky[lky++] = cur; if(cur*10+4<=10000)q.push(cur*10+4); if(cur*10+7<=10000)q.push(cur*10+7); } sort(lucky,lucky+lky); memset(delta,0,sizeof(delta)); memset(numCnt,0,sizeof(numCnt)); scanf("%d%d",&n,&m); sz = (int)sqrt(n); for(i=0;i<n;++i){ scanf("%d",&num[i]); numCnt[i/sz][num[i]]++; } int LB,RB; char str[25]; for(i=0;i<m;++i){ scanf("%s%d%d",str,&L,&R); L--; R--; LB = L/sz,RB = R/sz; int ans = 0; if(strcmp(str,"count")==0){ for(j = min((LB+1)*sz-1,R);j>=L;--j){//左块 for(k=0;k<lky;++k) ans += (num[j] + delta[LB] == lucky[k]); } for(j=LB+1;j<=RB-1;++j){//中块 for(k=0;k<lky;++k){ int tmp = lucky[k]-delta[j]; if(tmp>=0) ans += numCnt[j][tmp]; } } if(LB==RB){//如果在同一块,那么前面已经做好了 printf("%d\n",ans); continue; } for(j=RB*sz;j<=R;++j){//右块 for(k=0;k<lky;++k) ans += (num[j]+delta[RB]==lucky[k]); } printf("%d\n",ans); } else { scanf("%d",&d); LB = L/sz,RB = R/sz; for(j=min((LB+1)*sz-1,R);j>=L;--j){ numCnt[LB][num[j]]--; num[j] += d; numCnt[LB][num[j]]++; } for(j=LB+1;j<=RB-1;++j){ delta[j] += d; } if(LB==RB)continue; for(j=RB*sz;j<=R;++j){ numCnt[RB][num[j]]--; num[j] += d; numCnt[RB][num[j]]++; } } } return 0; }