小a正在玩一款即時戰略遊戲,現在他要用航空母艦對敵方陣地進行轟炸
地方陣地可以看做是n×mn×m的矩形
航空母艦總共會派出qq架飛機。
飛機有兩種,第一種飛機會轟炸以(xi,yi)(xi,yi)為中心,對角線長為lili的正菱形(也就是兩條對角線分別於xx軸 yy軸平行的正方形),而第二種飛機只會轟炸正菱形的上半部分(包括第xixi行)
(具體看樣例解釋)
現在小a想知道所有格仔被轟炸次數的異或和
注意:不保證被轟炸的格仔一定在矩形範圍內,若越界請忽略
第一行三個整數n,m,q分別表示矩陣的長/寬/詢問次數接下來q行,每行四個整數opt,x,y,l表示飛機型別,轟炸的座標,以及對角線長度
保證l為奇數!
乙個整數,表示所有格仔被轟炸次數的異或和示例1
4 5 41 2 2 1
1 3 3 5
1 3 2 3
2 2 4 3
2每次的操作矩陣即操作後的矩陣的值如下
最後把所有元素異或後為2
1⩽n,m⩽10001⩽q⩽5∗10^5 1⩽q⩽5∗10^5
保證opt=1/2,1⩽x,y,l⩽max(n,m)
讀入檔案過大,請使用較快的讀入方式
題目大意:
給出乙個n*m的矩形,然後有兩個操作.
1操作,對乙個給出的菱形,對菱形範圍內的東西進行+1。
2操作,對乙個上半菱形的區域,進行+1操作。
最後求矩形內各個數的異或和。
思路:這個題目的操作都是對乙個範圍整體+1,讓我們很容易想起樹狀陣列的區間操作。但是樹狀陣列是乙個規則的矩形,或者一維的操作。這裡是乙個菱形。所以具體操作是不一樣。
在矩形中,我們在四個角上進行++--,然後利用差分的性質,就解決了區間更新,但是在這裡,想破腦汁,也沒想出怎麼進行++--。因為矩形的差分是橫著或者豎著的,最後的求和非常容易,但是這裡不一樣。最後看了題解豁然大悟,原來差分還可以動態的來,本行的差分陣列使用完了,還可以把差分陣列下傳,繼續在下一層繼續起到作用,這是神奇的操作。
想來,這真是一道關於差分的好題。
那麼差分陣列如何進行標記,標記如何動態下傳呢,就看一下圖。
圖中的綠色是要進行區間操作的菱形。紅色圓圈是打的+1操作,藍色圓圈是打的-1操作。它們是成對出現的,每個紅色圓圈都有乙個藍色圓圈來消除它。 它們的標記傳遞方向是那個紫色的箭頭。所以有四種傳遞方向。就要有四個標記陣列。這樣傳遞的話就可以按行遍歷,邊遍歷邊下傳。
由於可能出現越界的情況,但是標記還是需要處理的。所以就要加個偏移量來進行處理,但是最後計算,只是算原來的矩形。
具體打標記和下傳標記的操作看**。
**:
#include using namespace std;
#define ll long long
const int maxn = 3e3+100,l=1e3;
const int maxm = 1e5 + 100;
const ll inf=1e16;
int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],d[maxn][maxn];
int n, m,q;
void up(int x,int y,int l)
void down(int x,int y,int l)
int main()
}printf("%d\n",res);
return 0;
}
小a的轟炸遊戲(差分,字首和)
題目傳送門 題意 給出乙個n m的矩形,然後有兩個操作.1操作,對乙個給出的菱形,對菱形範圍內的東西進行 1。2操作,對乙個上半菱形的區域,進行 1操作。最後求矩形內各個數的異或和。思路 在矩形中,我們在四個角上進行 然後利用差分的性質,就解決了區間更新,但是在這裡,想破腦汁,也沒想出怎麼進行 因為...
動態差分 二維字首和 小a的轟炸遊戲
小a正在玩一款即時戰略遊戲,現在他要用航空母艦對敵方陣地進行轟炸 地方陣地可以看做是n m n mn m的矩形 航空母艦總共會派出q qq架飛機。飛機有兩種,第一種飛機會轟炸以 xi yi xi,yi xi,yi 為中心,對角線長為l i lili的正菱形 也就是兩條對角線分別於x xx軸 y yy...
程式設計題 小Q的歌單(動態規劃)
輸入描述 每個輸入包含乙個測試用例。每個測試用例的第一行包含乙個整數,表示歌單的總長度k 1 k 1000 接下來的一行包含四個正整數,分別表示歌的第一種長度a a 10 和數量x x 100 以及歌的第二種長度b b 10 和數量y y 100 保證a不等於b。輸出描述 輸出乙個整數,表示組成歌單...