这题思路很是清奇

树状数组or线段树应该是挺好想的,but 位置是一维,位数是一维,再加上每一维的数字,开三维的线段树,树状数组肯定凉凉~~~

离线的做法就是这样冒出来滴,枚举位数(1--10),对于当前的位数,构造树状数组,然后处理询问和操作,这样省去了一维

不得不说很巧妙

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
using namespace std;

struct node
{
    char ch;
    int x,y,l,r,d,p;
    int ans;
}t[100100];

int T,n,m,P;
int f[100100][12];
int a[100100],pre[100100];

int lowbit(int x)
{
    return x & (-x);
}

void add(int x,int d,int pos)
{
    while(x <= n)
    {
        f[x][pos] += d;
        x += lowbit(x);
    }
}

int sum(int x,int pos)
{
    int su = 0;
    while(x > 0)
    {
        su += f[x][pos];
        x -= lowbit(x);
    }
    return su;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n; ++i) scanf("%d",&a[i]);
        for(int i = 1;i <= m; ++i)
        {
            cin>>t[i].ch;
            if(t[i].ch == 'Q') scanf("%d%d%d%d",&t[i].l,&t[i].r,&t[i].d,&t[i].p);
            else scanf("%d%d",&t[i].x,&t[i].y);
        }
        P = 1;   
        for(int i = 1;i <= 10; ++i)
        {
            memset(f,0,sizeof(f));
            memset(pre,0,sizeof(pre));
            for(int j = 1;j <= n; ++j)
            {
                add(j,1,(a[j] / P) % 10);
                pre[j] = (a[j] / P) % 10;   //(a[j] / P) % 10 表示a[j]的第i位
            }
            for(int j = 1;j <= m; ++j)
            {
                if(t[j].ch == 'Q' && t[j].d == i)
                    t[j].ans = sum(t[j].r,t[j].p) - sum(t[j].l - 1,t[j].p);
                else
                if(t[j].ch == 'S')
                {
                    int w = (t[j].y / P) % 10;
                    if(w != pre[t[j].x])
                    {
                        add(t[j].x,-1,pre[t[j].x]);
                        add(t[j].x,1,w);
                        pre[t[j].x] = w;
                    }
                }
            }
            P *= 10;
        }
        for(int i = 1;i <= m; ++i)
            if(t[i].ch == 'Q') printf("%d\n",t[i].ans);
    }
    return 0;
}