Argestes and Sequence
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 583 Accepted Submission(s): 147
Problem Description
Argestes has a lot of hobbies and likes solving query problems especially. One day Argestes came up with such a problem. You are given a sequence a consisting of N nonnegative integers, a[1],a[2],...,a[n].Then there are M operation on the sequence.An operation can be one of the following:
S X Y: you should set the value of a[x] to y(in other words perform an assignment a[x]=y).
Q L R D P: among [L, R], L and R are the index of the sequence, how many numbers that the Dth digit of the numbers is P.
Note: The 1st digit of a number is the least significant digit.
S X Y: you should set the value of a[x] to y(in other words perform an assignment a[x]=y).
Q L R D P: among [L, R], L and R are the index of the sequence, how many numbers that the Dth digit of the numbers is P.
Note: The 1st digit of a number is the least significant digit.
Input
In the first line there is an integer T , indicates the number of test cases.
For each case, the first line contains two numbers N and M.The second line contains N integers, separated by space: a[1],a[2],...,a[n]—initial value of array elements.
Each of the next M lines begins with a character type.
If type==S,there will be two integers more in the line: X,Y.
If type==Q,there will be four integers more in the line: L R D P.
[Technical Specification]
1<=T<= 50
1<=N, M<=100000
0<=a[i]<=$2^{31}$ - 1
1<=X<=N
0<=Y<=$2^{31}$ - 1
1<=L<=R<=N
1<=D<=10
0<=P<=9
For each case, the first line contains two numbers N and M.The second line contains N integers, separated by space: a[1],a[2],...,a[n]—initial value of array elements.
Each of the next M lines begins with a character type.
If type==S,there will be two integers more in the line: X,Y.
If type==Q,there will be four integers more in the line: L R D P.
[Technical Specification]
1<=T<= 50
1<=N, M<=100000
0<=a[i]<=$2^{31}$ - 1
1<=X<=N
0<=Y<=$2^{31}$ - 1
1<=L<=R<=N
1<=D<=10
0<=P<=9
Output
For each operation Q, output a line contains the answer.
Sample Input
1 5 7 10 11 12 13 14 Q 1 5 2 1 Q 1 5 1 0 Q 1 5 1 1 Q 1 5 3 0 Q 1 5 3 1 S 1 100 Q 1 5 3 1
Sample Output
5 1 1 5 0 1
——————————————————————分割线——————————————————
题目大意:
给你一个n个数的序列,有两种操作
1:Q L R D P 查询区间[L,R]中第D位为P的数的个数
2:S X Y 替换第X个的元素为Y
思路:
范围为10的5次方
c[k][i][j]表示lowbit(k)区间内第i位为j的数的个数,这样会内存为10的7次方,爆内存,如果用离线操作,就可以减掉一个维度
保存所有的操作,然后进行10次的树状数组就行了
那么这题就是基本的树状数组维护区间和了
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
#define forl(i,s,n) for(int i=s;i<n;++i)
#define forle(i,s,n) for(int i=s;i<=n;++i)
#define forg(i,s,n) for(int i=s;i>n;--i)
#define forge(i,s,n) for(int i=s;i>=n;--i)
#define mes(s,c) memset(s,c,sizeof(s))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
template<class T> T Pow(T x,T y){int ret=1;while(y){ret*=x;y--;}return ret;}
template<class T> T lowbit(T x){return x&-x;}
const int maxn=100001;
using namespace std;
int n,m;
int c[maxn][10];
int a[maxn],aa[maxn];
int ans[maxn];
struct operation
{
int l,r,d,p,x,y;
int s;
}Op[maxn];
void update(int s,int p,int v)
{
for(int i=p;i<=n;i+=lowbit(i)){
if(s==0) c[i][v]++;
else c[i][v]--;
}
}
int getsum(int p,int v)
{
int sum=0;
for(int i=p;i>0;i-=lowbit(i)){
sum+=c[i][v];
}
return sum;
}
int query(int l,int r,int v)
{
return getsum(r,v)-getsum(l-1,v);
}
int main()
{
int T;
cin>>T;
while(T--){
scanf("%d %d",&n,&m);
forle(i,1,n) {
scanf("%d",&a[i]);
aa[i]=a[i];
}
forl(i,0,m) {
char op[2];int l,r,d,p,x,y;
scanf("%s",op);
if(op[0]=='Q') {
scanf("%d %d %d %d",&l,&r,&d,&p);
Op[i].s=0,Op[i].l=l,Op[i].r=r,Op[i].d=d,Op[i].p=p;//o为查询
}else {
scanf("%d %d",&x,&y);
Op[i].s=1,Op[i].x=x,Op[i].y=y;//1为修改
}
}
forle(i,1,10) {
mes(c,0);
forle(j,1,n) {
aa[j]=a[j];
int t=a[j]/Pow(10,i-1)%10;
update(0,j,t);
}
forl(j,0,m) {
if(Op[j].s==1) {
int t=aa[Op[j].x]/Pow(10,i-1)%10;
update(1,Op[j].x,t);
t=Op[j].y/Pow(10,i-1)%10;
update(0,Op[j].x,t);
aa[Op[j].x]=Op[j].y;
}else {
if(Op[j].d==i){
ans[j]=query(Op[j].l,Op[j].r,Op[j].p);
}
}
}
}
forl(i,0,m)
if(Op[i].s==0) printf("%d\n",ans[i]);
}
return 0;
}