题意:给N个数,有两种操作,S x y 将a[x]变为y;Q x y d p 寻找[x,y]之内第d位的数为p的个数。
思路:开始一想,裸的线段树呀,敲了之后,MLE,然后一愣,有点傻眼了,卡空间。然而正解是分块,就是把N分成
N−−√
份,再处理,写跪了N发之后才A。也是爽。各种WA,TLE。复杂度N*
N−−√
。
http://acm.hdu.edu.cn/showproblem.php?pid=5057
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define rep(i,a,b) for(int i = a ; i <= b ; i ++)
#define rrep(i,a,b) for(int i = b ; i >= a ; i --)
#define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next)
#define cls(a,x) memset(a,x,sizeof(a))
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5+5;
const int MAXE = 2e5+5;
typedef long long LL;
int T,n,m,k;
int A[400][11][10];
int NUM[MAXN];
int st,lt;
int tmp;
void START() {
st = sqrt(n);
lt = st * st == n ? st : st + 1;
int base = 0;
cls(A,0);
rep(i,1,lt) {
rep(j,1,st) {
if(base+j > n) return ;
tmp = NUM[base + j];
rep(ia,1,10) {
A[i][ia][tmp%10] ++;
tmp /= 10;
}
}
base += st;
}
}
void out() {
rep(i,1,n) printf("%d ",NUM[i]);
puts("\n");
printf("st : %d lt : %d\n\n",st,lt);
rep(i,1,lt) {
rep(ia,1,10) {
rep(ib,0,9) {
printf("%d ",A[i][ia][ib]);
}
puts("");
}
puts("");
}
puts("\n");
}
void Update(int pos,int num) {
int oldnum = NUM[pos];
NUM[pos] = num;
int nowpos = (pos + (st - 1)) / st;
tmp = oldnum;
rep(ia,1,10) {
A[nowpos][ia][tmp%10] --;
tmp /= 10;
}
tmp = num;
rep(ia,1,10) {
A[nowpos][ia][tmp%10] ++;
tmp /= 10;
}
}
int ANS ;
int digit[11];
void Query(int left,int right,int d,int p) {
int L = (left + st - 1 ) / st + 1; int R = (right + st - 1) / st - 1;
if(L > R) {
rep(i,left,right) {
if((NUM[i]/digit[d])%10==p)ANS ++;
}
}
else {
rep(i,L,R) {
ANS += A[i][d][p];
}
rep(i,left,(L-1)*st) {
if((NUM[i]/digit[d])%10==p)ANS ++;
}
rep(i,R*st+1,right) {
if((NUM[i]/digit[d])%10==p)ANS ++;
}
}
}
int ReadInt() {
char tempc; int minus = 1; int ret = 0; scanf("%c",&tempc);
while(tempc < '0' || tempc > '9') { if(tempc == '-') minus = -1 ; scanf("%c",&tempc); }
while(tempc >= '0' && tempc <= '9') { ret = ret * 10 + tempc - '0' ; scanf("%c",&tempc); }
return ret * minus;
}
void input() {
scanf("%d %d",&n,&m);
char op[5];
rep(i,1,n) scanf("%d",&NUM[i]);
digit[1] = 1;
rep(i,2,10) digit[i] = digit[i-1] * 10;
START();
int x,y,d,p;
rep(i,1,m) {
scanf("%s",op);
if(op[0] == 'S') {
scanf("%d %d",&x,&y);
Update(x,y);
}
else {
scanf("%d %d %d %d",&x,&y,&d,&p);
ANS = 0;
Query(x,y,d,p);
printf("%d\n",ANS);
}
}
}
void solve() {
}
int main(void) {
scanf("%d",&T);
while(T--) {
input();
solve();
}
return 0;
}