853. Сережа и массив

 

У Сережи есть массив, состоящий из n целых чисел a1, a2, ..., an. Сережа активный мальчик, поэтому сейчас он собирается выполнить m операций. Каждая из этих операций будет иметь один из трех следующих видов:

·        Сделать vi-ый элемент массива равным xi. Другими словами, выполнить присвоение avi = xi.

·        Увеличить каждый элемент массива на yi. Другими словами, выполнить n присвоений ai  = ai +  yi (1 ≤ i ≤ n).

·        Выписать на листок qi-ый элемент массива. То есть элемент aqi.

Помогите Сереже, выполните все его операции.

 

Вход. В первой строке записаны целые числа n, m (1 ≤ n, m ≤ 105). Во второй строке записаны n целых чисел a1, a2, ..., an (1 ≤ ai ≤ 109) – исходный массив.

Следующие m строк описывают операции, i-ая строка описывает i-ую операцию. Первое число в i-ой строке – целое число ti (1 ≤  ti  ≤ 3), которое обозначает тип операции.

·        Если ti  = 1, то далее следуют два целых числа vi и xi (1 ≤  vi  ≤ n, 1 ≤  xi  ≤ 109).

·        Если ti  = 2, то далее следует целое число yi (1 ≤  yi  ≤ 104).

·        Если же ti  = 3, то далее следует целое число qi (1 ≤  qi ≤ n).

 

Выход. Для каждой операции третьего типа выведите значение aqi. Значения выводите в порядке следования соответствующих запросов во входных данных.

 

Пример входа 1

Пример выхода 1

5 6

1 2 3 4 5

3 1

2 10

1 1 5

3 1

2 10

3 1

1

5

15

 

 

Пример входа 2

Пример выхода 2

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

 

 

РЕШЕНИЕ

обработка массива

 

Анализ алгоритма

Прочитаем входной массив a. Заведем переменную add, которую инициализируем нулем. При выполнении операции второго типа (увеличение каждого элемента массива на yi) выполним прибавление add += yi. Таким образом при отсутствии операций первого типа (присваиваний avi = xi) конечное состояние элемента ai будет равняться начальному состоянию ai плюс add. Тогда для сохранения последнего свойства в случае первой операции будем присваивать avi = xiadd.

 

Пример

Рассмотрим первый пример. Пусть ai – состояние массива в памяти, ai– реальное состояние массива. Начальное состояние массива:

Поскольку ai = ai + add, но сначала add = 0, то ai = ai. То есть изначально физически каждый элемент массива равен самому себе.

Прибавляем 10 ко всем числам массива, add = add + 10 = 10. Имеет место соотношение: ai = ai + add.

Следующий запрос: a1= 5. Физически следует совершить присваивание

a1 = 5add,

после чего массив примет вид:

При запросе на вывод первого элемента получим a1 = a1 + add = -5 + 10 = 5.

Снова прибавим 10 ко всем числам массива: add = add + 10 = 20.

Первый элемент равен a1 = a1 + add = -5 + 20 = 15.

 

Реализация алгоритма

Объявим рабочий массив a.

 

#define MAX 100010

int a[MAX];

 

Читаем входной массив.

 

scanf("%d %d",&n,&m);

for(i = 1; i <= n; i++)

  scanf("%d",&a[i]);

 

Инициализируем переменную add.

 

add = 0;

 

Последовательно обрабатываем m операций. Тип операции читаем в переменную t.

 

for(i = 0; i < m; i++)

{

  scanf("%d",&t);

 

Выполняем присвоение avi = xi

 

  if (t == 1)

  {

    scanf("%d %d",&v,&x);

    a[v] = x - add;

  } else

 

Увеличиваем каждый элемент массива на yi.

 

  if (t == 2)

  {

    scanf("%d",&y);

    add += y;

  } else

 

Выводим qi-ый элемент массива.

 

  {

    scanf("%d",&q);

    printf("%d\n",a[q] + add);

  }

}