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; }