这天,可爱的小托米得到了n堆积木,且第i堆积木初始时有ai块积木.
小托米很快就喜欢上了玩积木.
他会作出三种操作:
1.把第v堆的积木数量更改为x.
2.在每堆积木的上面都加上y个积木.
3.数第q堆积木的积木个数.
由于这天可爱的小托米实在是太困了,所以他请你帮他完成这些操作.
输入描述:
第一行两个整数n,m.
第二行n个整数,第i个整数代表ai的值.
接下来m行,每行代表一个操作:
第一个整数t代表操作的类型
若t=1,则接下来两个整数v,x,代表操作1.
若t=2,则接下来一个整数y,代表操作2.
若t=3,则接下来一个整数q,代表操作3.
输出描述:
对于每个操作3,输出其对应的答案.
示例1
输入
10 11
1 2 3 4 5 6 7 8 9 10
3 2
3 9
2 10
3 1
3 10
1 1 10
2 10
2 10
3 1
3 10
3 9
输出
2
9
11
20
30
40
39
备注:
1≤n,m≤ 105
1≤ai≤109
1≤t≤3
1≤v≤ n,1≤ x≤109
1≤y≤104
1≤q≤n
模拟…然后就超时了,在群里大佬的教导下才明白了这个巧妙绝伦的思路,就是在加的时候,无需循环然后每一堆都加,只要维护一个tag来保存全局所添加的x,然后第一在将某一堆数量改为x时现在就要改为x-tag,因为已经有这个tag,也就是相当于所有的堆都有这个基础的数量,然后第三输出的时候就要加上tag再输出了
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN=100050;
long long a[MAXN];
int main(void){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
int tag=0;
while(m--){
int t;
int v,x,y,q;
scanf("%d",&t);
if(t==1){
scanf("%d%d",&v,&x);
a[v]=x-tag;
}
else if(t==2){
scanf("%d",&y);
tag+=y;
}
else if(t==3){
scanf("%d",&q);
printf("%lld\n",tag+a[q]);
}
}
return 0;
}