对树状数组和线段树的时间复杂度计算一直存在问题啊。
这题离线之后,分别计算第一位,第二位等等等的情况,然后输出结果,总感觉这样处理这么麻烦会超时,只能说这种题目一般不会卡最大时间复杂度,否则肯定tle了。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAX=100001;
int tree[MAX][10]; //第二维表示数字是几
int num[MAX];
int mark[MAX];
int n,m;
struct node
{
int p;
int a,b,c,d,ans;
} op[MAX];
int lowbit(int x)
{
return (x)&(-x);
}
void update(int a,int b,int v)
{
while (a<=n)
{
tree[a][b]+=v;
a+=lowbit(a);
}
}
int sum(int a,int b)
{
int s=0;
while (a>0)
{
s+=tree[a][b];
a-=lowbit(a);
}
return s;
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&num[i]);
for (int i=1;i<=m;i++)
{
char s[10];
scanf("%s",s);
if (s[0]=='Q')
{
op[i].p=2;
scanf("%d%d%d%d",&op[i].a,&op[i].b,&op[i].c,&op[i].d);
}
else
{
op[i].p=1;
scanf("%d%d",&op[i].a,&op[i].b);
}
}
long long int pp=1;
for (int i=1;i<=10;i++)
{
for (int t=1;t<=n;t++)
for (int k=0;k<=9;k++)
tree[t][k]=0;
for (int t=1;t<=n;t++)
{
int v=(num[t]/pp)%10;
update(t,v,1);
mark[t]=v;
}
for (int t=1;t<=m;t++)
{
if (op[t].p==1)
{
int v=(op[t].b/pp)%10;
update(op[t].a,v,1);
update(op[t].a,mark[op[t].a],-1);
mark[op[t].a]=v;
}
else if (op[t].c==i)
op[t].ans=sum(op[t].b,op[t].d)-sum(op[t].a-1,op[t].d);
}
pp*=10;
}
for (int i=1;i<=m;i++)
if (op[i].p==2)
printf("%d\n",op[i].ans);
}
}