poj1195 mobile/ bzoj 1176
這兩個題題意完全相同,放在一起說吧
題意:你有乙個n*n的棋盤,每個格仔內有乙個整數,初始時的時候全部為0,現在需要維護兩種操作:
命令引數限制
內容1 x y a
1<=x,y<=n,a是正整數
將格仔x,y裡的數字加上a
2 x1 y1 x2 y2
1<=x1
<= x2
<=n
1<=y1
<= y2
<=n
輸出x1 y1 x2 y2這個矩形內的數字和
無終止程式
標準的三維偏序問題,三個維度分別為x,y和時間t。
在poj1195中,n<=1024,可以用二維樹狀陣列來做,非常簡單。
但在bzoj1176中,n<=500000,空間開不下,所以用cdq分治+一維樹狀陣列來做。
對於所有的查詢操作,我們拆分成4個。分別查詢(0,0)到(x1-1,y1-1),(x2,y2),(x2,y1-1),(x1-1,y2)四個矩形的數字和
然後用容斥原理加減一下就可以算出(x1,y1),(x2,y2)的矩形數字和了。
cdq分治中,首先按x來排序,對t這個維度進行分治。
那麼t<=mid的更新操作都能影響到t'>=mid+1的查詢結果。
所以在cdq(l,r)中,按照x從小到大掃一遍所有操作,遇到更新操作就在樹狀陣列上插入y值,
遇到查詢操作就給該操作的結果加上樹狀陣列上查詢到的sum(1,y)的值。
接下來用類似歸併排序的方法,把t<=mid的操作都放到陣列左半部分,t>=mid+1的操作都放到右半部分
這麼做之後兩半部分的x依然是有序的,就可以遞迴處理兩半部分之間的更新操作對查詢操作產生的影響了。
下面是**,按照poj1195的輸入格式寫的
#include#include#include#include#include#include#define ll long long
using namespace std;
int n;
int tree[1029];
int cnt=0;
int anscnt=0;
int ans[60111];
struct operation
operation(int x_,int y_,int k_,int ansid_,bool type_,int id_):
x(x_),y(y_),k(k_),ansid(ansid_),type(type_),id(id_){}
operation(){}
bool operator <(const operation& rhs)const
void cdq(int l,int r)
for(int i=l;i<=r;++i)
if(op[i].id<=mid&&!op[i].type)
add(op[i].y,-op[i].k);
for(int i=l;i<=r;++i)
if(op[i].id<=mid)
temp[lp++]=op[i];
else temp[rp++]=op[i];
for(int i=l;i<=r;++i)
op[i]=temp[i];
cdq(l,mid);cdq(mid+1,r);
}int main()
else if(o==2)
} sort(op+1,op+cnt+1);
cdq(1,cnt);
for(int i=1;i<=anscnt;++i)
printf("%d\n",ans[i]);
return 0;
}
bzoj1195 最短母串
1 練習了string類,string中查詢,找不到的話會返回 s.npos乙個變數,而不是返回一般的s.end 2 這題還可以,ac自動機上狀壓bfs,找最短路,實際上是dp,但是轉移都是加1,所以可以抽象為邊長為一從起始狀態到最終狀態的最短路,因為為邊長1,又可以轉為bfs。3 include ...
poj1195解題報告 樹狀陣列
題目大意 在乙個2維的x,y座標軸內,被劃分成了正方形,該正方形是由s s的矩陣構成 行和列都是從0 s 1 可以輸入0,1,2,3這些指令 指令 0 0 s 初始化s s的矩陣,也就是全部置0.指令1 1 x y a 向正方形 x,y 中加入手機數為a 注意a可能為負數 但是題目中保證正方形 x,...
POJ 1195 二維樹狀陣列
題意 現對矩陣進行以下操作。0,將乙個方陣初始化為全0。1,某個位置的數加上乙個值。2,詢問某個區域的數字和。要求對每個詢問求出其和。使用二維樹狀陣列即可 matrix x1,y1,x2,y2 sum x2,y2 sum x1 1,y1 1 sum x2,y1 1 sum x1 1,y2 inclu...