题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5057
分块,维护每块中每位的每个数位出现的次数。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 100100; 5 const int maxm = 1010; 6 int be[maxn], b[maxm][11][11]; 7 int n, sz, q, a[maxn]; 8 char cmd[5]; 9 10 int mul(int x, int n) { 11 int ret = 1; 12 while(n) { 13 if(n & 1) ret *= x; 14 n >>= 1; 15 x *= x; 16 } 17 return ret; 18 } 19 20 void update(int pos, int val) { 21 if(a[pos] == val) return; 22 for(int i = 1; i <= 10; i++) { 23 b[be[pos]][i][a[pos]%10]--; 24 a[pos] /= 10; 25 } 26 a[pos] = val; 27 for(int i = 1; i <= 10; i++) { 28 b[be[pos]][i][val%10]++; 29 val /= 10; 30 } 31 } 32 33 int query(int l, int r, int d, int p) { 34 int ret = 0; 35 for(int i = l; i <= r; ) { 36 if(i + sz <= r && i % sz == 0) { 37 ret += b[be[i]][d][p]; 38 i += sz; 39 } 40 else { 41 ret += (a[i] / mul(10, d-1) % 10 == p); 42 i++; 43 } 44 } 45 return ret; 46 } 47 48 signed main() { 49 // freopen("in", "r", stdin); 50 int T, l, r, d, p; 51 scanf("%d", &T); 52 while(T--) { 53 memset(b, 0, sizeof(b)); 54 scanf("%d%d",&n,&q); 55 sz = (int)sqrt(n); 56 for(int i = 0; i < n; i++) { 57 scanf("%d", &a[i]); 58 be[i] = i / sz; 59 int val = a[i]; 60 for(int j = 1; j <= 10; j++) { 61 b[be[i]][j][val%10]++; 62 val /= 10; 63 } 64 } 65 while(q--) { 66 scanf("%s", cmd); 67 if(cmd[0] == 'Q') { 68 scanf("%d%d%d%d",&l,&r,&d,&p); 69 printf("%d ", query(--l, --r, d, p)); 70 } 71 else { 72 scanf("%d%d",&d,&p); 73 update(--d, p); 74 } 75 } 76 } 77 return 0; 78 }