搬运博文最后一篇,嘿嘿嘿~~~
Problem  Description:

小托米真的很可爱呀(>_<)
这天,可爱的小托米得到了n堆积木,且第i堆积木初始时有ai块积木.
小托米很快就喜欢上了玩积木.
他会作出三种操作:
1.把第v堆的积木数量更改为x.
2.在每堆积木的上面都加上y个积木.
3.数第q堆积木的积木个数.
由于这天可爱的小托米实在是太困了,所以他请你帮他完成这些操作.

Input:

第一行两个整数n,m.
第二行n个整数,第i个整数代表ai的值.
接下来m行,每行代表一个操作:
第一个整数t代表操作的类型
若t=1,则接下来两个整数v,x,代表操作1.
若t=2,则接下来一个整数y,代表操作2.

若t=3,则接下来一个整数q,代表操作3.

Output:

对于每个操作3,输出其对应的答案.

Sample  Input:

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

Sample  Output:

2
9
11
20
30
40

39

思路:这道题中操作2如果你用for(i=0;i<n;i++){  a [ i ]+=y;}这种方法的话会超时,因此要进行优化,即用flag做标记,计算出flag(flag用来统计一共要加多少y),然后经过一系列操作之后要输出a[ i ],就让初始值的a[ i ]+flag,就是最后a[ i ]的最终值,要注意的就是操作1,它不是让a[ v-1 ]=x,而是a[ v-1 ]=x-flag,具体操作可以看下面的代码。

My  DaiMa:
#include<stdio.h>
#include<iostream>
using namespace std;
typedef long long ll;
ll a[100003];
int main()
{
    ll n,m,t,q,y,x,v;
    while(~scanf("%lld%lld",&n,&m))
    {
        int flag=0;
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]);
        while(m--)
        {
            scanf("%lld",&t);
            if(t==3)
            {
                scanf("%lld",&q);
                printf("%lld\n",a[q-1]+flag);//用初始的值加上flag就是a[q-1]最终的值
            }
            else if(t==1)
            {
                scanf("%lld%lld",&v,&x);
                a[v-1]=x-flag;//如果不明白这里的话,可以带2个数进去试试
            }
            else if(t==2)
            {
                scanf("%lld",&y);
                flag+=y;
            }
        }
    }
    return 0;
}