BZOJ2683 簡單題 題解

2022-07-01 09:15:11 字數 1401 閱讀 8415

/*

1.若n比較小,則可以用二維的樹狀陣列或線段樹來做,但是500000,空間開不下,於是考慮離線cdq。

子矩陣的數字和表示為也就是二維字首和,因此乙個要查詢的子矩陣,

對其有影響的矩陣為s[x2][y2],s[x2][y1-1],s[x1-1][y2],s[x1-1][y1-1]這四個字首子矩陣

所以,在沒有修改操作的時候,這是乙個二維偏序了裸題

但當加入了操作順序這個玩意的時候,就是乙個三維偏序。

其實對於操作順序的處理也就是 cdq 分治的過程,而每次分治,處理的都僅限於左邊的修改對右邊查詢的影響。

為了判斷是查詢和修改,我用了乙個 opt 變數。

2.注意這個tim的妙用

通過和 vis 陣列結合,讓不屬於當前遞迴的bit中的貢獻被忽略

具體的忽略方式主要是在 ask() 裡面

為了和 ask() 配合, add() 函式做出改變,通過另一種方式清空並修改。

3.有乙個妙點是對於 opt 的利用,通過這個,處理了將操作和詢問一同放入 p 的分辨問題

可以直接通過 while 盤掉,注意 while 邊界。

4.啊啊啊啊啊啊啊,易錯點,

不要把 sort(p+l,p+mid+1) 寫成 sort(p+1,p+mid+1)

調了我乙個小時多。。。(彩筆乙個)

5.雙倍經驗:[bzoj1176]mokia

*/#include

using

namespace

std;

const

int n = 800005

;const

int m = 2000005

;int

n,totp,totq,tim;

intopt,x,y,xx,yy,val;

intvis[m],ans[n],pos[n];

struct

point

}p[m];

struct

bit

void add(int x,int

val)

}int ask(int

x)}bit;

void solve(int l,intr)}

intmain();

}else

; p[++totp]=;

p[++totp]=;

p[++totp]=;}}

solve(

1,totp);

for(int i=1;i<=totq;i++)

printf(

"%d\n

",ans[pos[i]+1]-ans[pos[i]+2]-ans[pos[i]+3]+ans[pos[i]+4

]);

return0;

}

BZOJ 2683 簡單題 CDQ分治

n n矩陣,支援單點修改,查詢某乙個子矩陣內的和 n leq 500000 運算元 leq 200000 首先運用二維字首和的思想,把子矩陣的和拆成四個字首和。然後把詢問和修改看成 x,y,t 的三元組,t表示當前是第幾次操作。然後就變成三維偏序問題,對於每個詢問,找x,y,t均比它小的修改操作,再...

bzoj2683簡單題 cdq分治

time limit 50 sec memory limit 128 mb submit 1803 solved 731 submit status discuss 你有乙個n n的棋盤,每個格仔內有乙個整數,初始時的時候全部為0,現在需要維護兩種操作 命令引數限制 內容1 x y a 1 x,y ...

BZOJ2683 簡單題 分治 樹狀陣列

time limit 50 sec memory limit 128 mb submit status discuss 你有乙個n n的棋盤,每個格仔內有乙個整數,初始時的時候全部為0,現在需要維護兩種操作 命令引數限制 內容 1 x y a 1 x,y n,a是正整數 將格仔x,y裡的數字加上a ...