题目大意:
- 给一串数字,有两个操作:
- 操作1:将
l
−
r
l-r
l−r 的数字,变成每位数字之和。
- 操作2:求
a
x
a_x
ax 的数字。
解题思路:
- 预处理每个数字的反转之后的类型,当数字之和为
1
1
1 位数时,再次进行操作1就是本身
- 我们通过
B
I
T
BIT
BIT 进行区间累加,单点查询当前数字操作了多少次,然后直接与最大操作次数取一个最小值
#include<bits/stdc++.h>
using namespace std;
const int N = 200010;
struct BIT {
int C[N];
inline int lowbit(int x) {return x&-x;}
inline void add(int x,int v) {for(;x<N;x+=lowbit(x)) C[x]+=v;}
inline int ask(int x) {int res=0;for(;x>0;x-=lowbit(x)) res+=C[x];return res;}
inline int ask(int l,int r) {return ask(r)-ask(l-1);}
}tr;
int check(int x)
{
int sum=0;
while(x)
{
sum+=x%10;
x/=10;
}
return sum;
}
signed main()
{
int T;cin>>T;
while(T--)
{
int n,q;cin>>n>>q;
vector<int> a[n+1];
for(int i=1;i<=n;i++)
{
int x;cin>>x;
while(1)
{
a[i].push_back(x);
int f=check(x);
if(f==x) break;
x=f;
}
}
for(int i=1;i<=n;i++)
tr.C[i]=0;
while(q--)
{
int op;cin>>op;
if(op==1)
{
int l,r;cin>>l>>r;
tr.add(l,1),tr.add(r+1,-1);
}
else
{
int x;cin>>x;
cout<<a[x][min((int)a[x].size()-1,tr.ask(x))]<<endl;
}
}
}
return 0;
}