题目:
给一个n个数的数组,q次询问,如果是1,更新l~r的值,如果是二,输出a[x]的值。本来思路是暴力,对于每个a[i]调用一个sum函数更新,结果一直超时。题解思路是:对于一个很大的数,最多三次就会更新为一个10以内的数,比如999999999,一次更新为81,二次为9,之后不再更新,所以题解没有对a[i]<9的数进行更新操作了,并且用set容器记录了值大于9的数组的下标,对l~r的数组操作时,只操作数组值大于9的下标。
代码:
cin>>t;
while (t--)
{
scanf("%d%d",&n,&q);
vector <long long > a(n+1);//数组a,从一开始,所以开n+1个
set<int> s;记录下标的数组;
for (int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if (a[i]>9)
s.insert(i);//存入下标
}
while (q--)
{
scanf("%d",&m);
if (m==1)
{
scanf("%d%d",&l,&r);
int num=l;
while (!s.empty())//当有下标数组不为空是进行循环
{
auto x=s.lower_bound(num);//二分找到下标大于等于num的迭代器
if (x==s.end()||*x>r)//如果没有找到或者超出范围跳出循环
break;
a[*x]=sum(a[*x]);//更新数组
int p=*x;
s.erase(x);//删除x
if (a[p]>9)s.insert(p);//重新判断一下
num=p+1;//移向下一个
}
}
else {
scanf("%d",&l);
cout<<a[l]<<endl;
}
}
}