經過上次失敗後,蕾公尺莉亞決定再次發動紅霧異變,但為了防止被靈夢退治,她決定將紅霧以奇怪的陣勢釋放。
我們將幻想鄉看做是乙個 \(n \times m\) 的方格地區,一開始沒有任何乙個地區被紅霧遮蓋。蕾公尺莉亞每次站在某乙個地區上,向東南西北四個方向各發出一條無限長的紅霧,可以影響到整行/整列,但不會影響到她所站的那個地區。如果兩陣紅霧碰撞,則會因為密度過大而沉降消失。靈夢察覺到了這次異變,決定去解決它。但在解決之前,靈夢想要了解一片範圍紅霧的密度。可以簡述為兩種操作:
1 x y
蕾公尺莉亞站在座標 \((x,y)\) 的位置向四個方向釋放無限長的紅霧。
2 x1 y1 x2 y2
詢問左上點為 \((x1,y1)\),右下點為 \((x2,y2)\) 的矩形範圍內,被紅霧遮蓋的地區的數量。
認為站立的地方也是沉降。
維護兩棵線段樹,乙個維護行,乙個維護列,單點修改,區間查詢(樹狀陣列也可以)
設 \(r,c\) 分別代表行和列被覆蓋數量,答案為 $ r \times (y2 - y1 + 1) + c \times (x2 - x1 + 1) - 2 \times r \times c $ 。
減去兩倍 \(r \times c\) 的原因:去掉行列統計各一次。
#includeusing namespace std;
typedef long long ll;
const int maxn = 100000 + 7;
const int maxm = 200000 + 7;
int n, m, t;
template < typename tp >
void read(tp &x)
void init(void)
struct segment_tree
if(pos <= mid) modify(lfc, l, mid, pos);
else modify(rgc, mid + 1, r, pos);
val[x] = val[lfc] + val[rgc];
} int query(int x, int l, int r, int l, int r)
}row, column;
void operator1(void)
void operator2(void)
void work(void)
}int main(void)
luogu P3801 紅色的幻想鄉
嘟嘟嘟 首先人人都能想到是線段樹,不過二維線段樹肯定會mle tle的。我們換一種想法,不去修改整個區間,而是修改乙個點 開橫豎兩個線段樹,分別記錄哪些行和列被修改了。因為如果兩陣紅霧碰撞,則會因為密度過大而沉降消失,所以自然想到亦或。統計的時候求出這個矩形內有哪些行和列被修改了,接著把這些行和列的...
luogu3801 紅色的幻想鄉
給乙個初始值都是0的0 1矩陣,兩個操作 1.選擇乙個點,將其所在排和列 不包括該點 的數字取反。2.求乙個子矩形內的數字和。n,m,q 100000.n,m 100000,每個x線段樹都維護乙個有400000個節點的y線段樹,而x節點也要400000個,空間受不了。如果我們要更新一排,x線段樹沒有...
洛谷 P3801 紅色的幻想鄉(線段樹 容斥)
如果會二維線段樹的話,這個題目應該會好想一點,但是資料範圍不允許使用如果考慮一維線段樹的話,只能考慮每次的貢獻值 其實不難發現,我們建兩個線段樹,分別維護 x 軸和 y 軸,這樣對於每一次詢問,只要找到 x1,x2 有幾個標記的點 記為 x y1,y2 有幾個標記的點 記為 y 所以答案為 也就是減...