Codeforces Sereja and Array

weixin_34391854發表於2013-06-08

http://codeforces.com/problemset/problem/315/B

資料結構?

這題比賽時想到了線段樹,後來發現錯了,確定是資料結構方向的,一直想,想了可能有20分鐘的樣子,覺得可以水過去,然後就去水,然後過了,賽後這題被歸為資料結構,但是覺得這個分類有時候真的不太靠譜,不知道資料結構到底怎麼寫,但是看別人的程式碼,水過去的做法更多

題意:3個種操作

1  x val ,把陣列下標x的元素的值改為val

2 val , 把整個陣列每個元素的值都增加val

3 x , 查詢下標x的元素當前的值

 

問題的關鍵是修改某個單元的值,試想2操作做了好幾次,即整個陣列的值加了好幾個值,這時候執行1操作修改某個單元的值,那麼之前2操作累加上來的值對它就沒影響了,但是查詢其他單元的時候是要考慮之前2操作累加上來的值

我的做法是,用一個陣列來儲存來每次2操作後的累加情況。如果對某個單元執行了1操作,那麼記錄下當時是進行到哪一次2操作,下去查詢的時候,看看當時已經到了哪個2操作,用當時2操作累加的值減去上一次2操作累加的值,就是應該得到的累加值

說得有點亂,看程式碼更好懂,注意看delta陣列,pre陣列

 

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define N 100010
typedef long long ll;

struct Delta
{
    ll sum,val;
}del[N];
ll time,n,m,a[N];
int pre[N];

int main()
{
//  freopen("B_output.txt","w",stdout);
    //scanf("%d%d",&n,&m);
    cin >> n >> m;
    for(int i=1; i<=n; i++) cin >> a[i];
    memset(pre,0,sizeof(pre));
    del[0].sum = 0; del[0].val = 0;
    while(m--)
    {
        int op,x;
        ll val;
        scanf("%d",&op);
        if(op == 1)
        {
            cin >> x >> val;
            a[x] = val;
            pre[x] = time;
        }
        else if(op == 2)
        {
            ++time;
            cin >> val;
            del[time].val = val;
            del[time].sum = del[time-1].sum + del[time].val;
        }
        else
        {
            cin >> x;
            int p = pre[x];
            ll tmp = del[time].sum - del[p].sum;
            cout << a[x] + tmp << endl;
        }
    }
    return 0;
}

 

相關文章