您的位置:首页 > 其它

2016-scut-H. Lucky Array(分块)

2016-04-24 21:51 351 查看

H. Lucky Array

Time Limit: 10 Sec, Memory Limit: 256 MB

Description

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.

Input

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.

Output

For each operation of the second typeprint the single number on the single line — the number of lucky numbers in thecorresponding interval.

Sample 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

Sample Output

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
,numCnt
[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  分块