2014-10-04 16:53:30
思路:这题是个很裸的线段树 or 树状数组题,因为加了内存限制而变得有点意思。参考了别人博客,有两种做法:
(1)在线做法:将树状数组中的c[]数组变为:c[]和re[],分别表示数量 / 32768的商 和 数量除以32768后的余数,也就是原先的c[i] = c[i] * 32768 + re[i]。而c[]用char表示,re用signed short来表示,- =真是机智啊!最后c[]数组应该开成这样:c[maxn][10][10]。
(2)离线做法:先把所有操作读进来,然后枚举每一位,这样只用开c[maxn][10]的数组,int型直接上~~~。
这里附(1)的做法代码:
1 /************************************************************************* 2 > File Name: 5057.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Sat 04 Oct 2014 03:11:35 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <queue> 16 #include <iostream> 17 #include <algorithm> 18 using namespace std; 19 #define lp (p << 1) 20 #define rp (p << 1|1) 21 #define getmid(l,r) (l + (r - l) / 2) 22 #define MP(a,b) make_pair(a,b) 23 typedef long long ll; 24 const int INF = 1 << 30; 25 const int maxn = 100010; 26 const int mod = 1 << 15; 27 28 int T,N,M; 29 int A[maxn]; 30 char c[maxn][10][10]; 31 unsigned short re[maxn][10][10]; 32 33 int Lowbit(int x){ 34 return x & (-x); 35 } 36 37 void Update(int x,int d,int p,int v){ 38 int tmp; 39 while(x <= N){ 40 tmp = re[x][d][p] + v; 41 c[x][d][p] += tmp / mod; 42 re[x][d][p] = tmp % mod; 43 x += Lowbit(x); 44 } 45 } 46 47 int Getsum(int x,int d,int p){ 48 int res = 0; 49 while(x){ 50 res += c[x][d][p] * mod + re[x][d][p]; 51 x -= Lowbit(x); 52 } 53 return res; 54 } 55 56 int main(){ 57 char s[5]; 58 int tem,l,r,d,p,x,y; 59 scanf("%d",&T); 60 while(T--){ 61 scanf("%d%d",&N,&M); 62 memset(c,0,sizeof(c)); 63 memset(re,0,sizeof(re)); 64 for(int i = 1; i <= N; ++i){ 65 scanf("%d",A + i); 66 tem = A[i]; 67 for(int j = 0; j < 10; ++j){ 68 Update(i,j,tem % 10,1); 69 tem /= 10; 70 } 71 } 72 for(int i = 1; i <= M; ++i){ 73 scanf("%s",s); 74 if(s[0] == 'S'){ 75 scanf("%d%d",&x,&y); 76 tem = A[x]; 77 for(int j = 0; j < 10; ++j){ 78 Update(x,j,tem % 10,-1); 79 tem /= 10; 80 } 81 A[x] = y; 82 for(int j = 0; j < 10; ++j){ 83 Update(x,j,y % 10,1); 84 y /= 10; 85 } 86 } 87 else{ 88 scanf("%d%d%d%d",&l,&r,&d,&p); 89 printf("%d\n",Getsum(r,d - 1,p) - Getsum(l - 1,d - 1,p)); 90 } 91 } 92 } 93 return 0; 94 }