/*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 ...