时间:1s 空间:256M
题目描述:
数位之和的意思是某个整数每一位之和。比如的数位之和就是。
小信现在给你一个长度为 的数组,然后操作次,有两种操作:
-
代表将下标范围在内所有的, 修改为的数位之和
-
代表输出。
输入格式:
第一行两个整数,
第二行包括 个整数,。
接下来 行,每行代表一次操作。
输出格式:
对于每次操作2,输出一个整数表示答案。
样例1输入:
5 8
1 420 69 1434 2023
1 2 3
2 2
2 3
2 4
1 2 5
2 1
2 3
2 5
样例1输出:
6
15
1434
1
6
7
约定与提示:
,
。
对于样例1测试数据操作过程如下:
-
刚开始,,
-
对执行操作后,。
-
询问操作后,输出了。
-
对 执行操作后,。
-
询问操作后,输出。
主要思路:
我们可以发现如果对一个个位数进行求各个数位之和结果等于自己,也就是没有意义,我们用一个set来存储下标,如果这个数是个位数,那么就把这个下标删除。
set存储下标
for(int i=1;i<=n;i++)
{
cin>>a[i];
s.insert(i);
}
注:set会自动排序
set操作1
int l,r;
cin>>l>>r;
auto pos=s.lower_bound(l);//找到首个大于l的下标。
if(pos == s.end())//如果没找到
{
continue;//跳过
}
vector<int> v;//直接删除会有RE风险,存储要被删的下标
for(auto it=pos;it!=s.end();it++)//枚举
{
if(*it>r)//如果下标超了
{
break;//跳出
}
a[*it] = num(a[*it]);//不然就执行数位和操作
if(a[*it]<=9)//如果是个位数
{
v.push_back(*it);//那就删了(暂时存储)
}
}
for(auto it:v)
{
s.erase(it);//删除要被删的下标
}
set操作二
int x;
cin>>x;
cout<<a[x]<<'\n';
总体代码:
#include<bits/stdc++.h>
using namespace std;
int num(int x)
{
int num1=0;
while(x)
{
num1+=x%10;
x/=10;
}
return num1;
}
set<int> s;
int a[200010];
int main()
{
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s.insert(i);
}
while(q--)
{
int op;
cin>>op;
if(op == 1)
{
int l,r;
cin>>l>>r;
auto pos=s.lower_bound(l);//找到首个大于l的下标。
if(pos == s.end())//如果没找到
{
continue;//跳过
}
vector<int> v;//直接删除会有RE风险,存储要被删的下标
for(auto it=pos;it!=s.end();it++)//枚举
{
if(*it>r)//如果下标超了
{
break;//跳出
}
a[*it] = num(a[*it]);//不然就执行数位和操作
if(a[*it]<=9)//如果是个位数
{
v.push_back(*it);//那就删了(暂时存储)
}
}
for(auto it:v)
{
s.erase(it);//删除要被删的下标
}
}
else
{
int x;
cin>>x;
cout<<a[x]<<'\n';
}
}
return 0;
}