- [1 线段æ ï¼ååä¸ºçº¿æ®µä¿®æ¹æ ï¼](#1)
* [1.1 çº¿æ®µæ æ¦å¿µå»ºç«](#11)
+ [1.1.1 ç´¯å åæ°ç»å»ºç«](#111)
+ [1.1.2æ´æ°ç»ææ°ç»å»ºç«](#112)
* [1.2 çº¿æ®µæ æ¡ä¾å®æ](#12)
* [1.3 ä»ä¹æ ·çé¢ç®å¯ä»¥ç¨çº¿æ®µæ æ¥è§£å³ï¼](#13)
1 线段æ ï¼ååä¸ºçº¿æ®µä¿®æ¹æ ï¼
çº¿æ®µæ æè¦è§£å³çé®é¢æ¯ï¼åºé´çä¿®æ¹ï¼æ¥è¯¢åæ´æ°ï¼å¦ä½æ´æ°æ¥è¯¢çæ´å¿«ï¼
线段æ ç»ææä¾ä¸ä¸ªä¸»è¦çæ¹æ³, å设大å°ä¸ºNçæ°ç»ï¼ä»¥ä¸ä¸ä¸ªæ¹æ³ï¼åè¦è¾¾å°O(logN) ï¼
```Java
// Lå°Rèå´çæ°ï¼æ¯ä¸ªæ°å ä¸V
void add(int L, int R, int V, int[] arr);
// Lå°Rèå´çæ°ï¼æ¯ä¸ªæ°é½æ´æ°æV
void update(int L, int R, int V, int[] arr);
// Lå°Rèå´çæ°ï¼ç´¯å åè¿å
int getSum(int L, int R, int[] arr);
```
1.1 çº¿æ®µæ æ¦å¿µå»ºç«
1.1.1 ç´¯å åæ°ç»å»ºç«
1ã对äºå¤§å°ä¸ºnçæ°ç»ï¼æä»¬äºåå®ï¼æ¯æ¬¡äºåæä»¬é½è®°å½ä¸ä¸ªä¿¡æ¯
2ãå¯¹äºæ¯æ¬¡äºåï¼æç«æ ç»æï¼æä»¬æ³æ¿ä»»ä½åºé´çä¿¡æ¯ï¼å¯ä»¥ç±æä»¬çäºåç»æç»åå¾å°ãä¾å¦æä»¬1å°8çæ°ç»ï¼å¯ä»¥äºåå¾å°çä¿¡æ¯ä¸ºï¼
```
graph TD
'1-8'-->'1-4'
'1-8'-->'5-8'
'1-4'-->'1-2'
'1-4'-->'3-4'
'5-8'-->'5-6'
'5-8'-->'7-8'
'1-2'-->'1'
'1-2'-->'2'
'3-4'-->'3'
'3-4'-->'4'
'5-6'-->'5'
'5-6'-->'6'
'7-8'-->'7'
'7-8'-->'8'
```
æ¯ä¸ä¸ªèç¹çä¿¡æ¯ï¼å¯ä»¥ç±è¯¥èç¹å·¦å³å©åä¿¡æ¯å¾å°ï¼æä¸å±ä¿¡æ¯å°±æ¯èªå·±çä¿¡æ¯ãç±ä»¥ä¸çè§åï¼å¯¹äºN个æ°ï¼æä»¬éè¦ç³è¯·2N-1个空é´ç¨æ¥ä¿åèç¹ä¿¡æ¯ã妿Nå¹¶éçäº2çææ¬¡æ¹ï¼æä»¬æNè¡¥æ2çææ¬¡æ¹çé¿åº¦ï¼ç¨æ¥ä¿è¯æä»¬æå»ºåºæ¥çä¿¡æ¯æ°æ¯æ»¡äºåæ ãä¾å¦æä»¬çé¿åº¦æ¯6ï¼æä»¬è¡¥å°8个ï¼å两个ä½ç½®å¼ä¸º0ã
对äºä»»æçN,æä»¬éè¦åå¤å¤å°ç©ºé´ï¼å¯ä»¥æNè¡¥æ2çææ¬¡æ¹ï¼å¾å°çäºåä¿¡æ¯é½è£
ä¸ï¼çæ¡æ¯4Nã4Nè½ç¶æå¯è½å¤å空é´ï¼ä½æ¯å¤ä½ç空é´é½æ¯0ï¼å¹¶æ å½±åï¼èä¸å
¼å®¹N为任æå¼çæ
åµ
ä¾å¦å个æ°é¿åº¦çæ°ç»arr[4]{3,2,5,7}ï¼æä»¬å¾å°ç´¯å åçäºåä¿¡æ¯ä¸ºå¦ä¸çæ ï¼
```
graph TD
'1å°4=17'-->'1å°2=5'
'1å°4=17'-->'3å°4=12'
'1å°2=5'-->'3'
'1å°2=5'-->'2'
'3å°4=12'-->'5'
'3å°4=12'-->'7'
```
æä»¬ç³è¯·4Nç空é´ï¼å³16ï¼arr[16]ã0ä½ç½®ä¸ç¨ãarr[1]=17ï¼arr[2]=5,arr[3]=12,arr[4]=3,arr[5]=2,arr[6]=5,arr[7]=7ãå©ä¸ä½ç½®é½ä¸º0ãä»»ä½ä¸ä¸ªèç¹å·¦å©å䏿 为2iï¼å³å©å䏿 为2i+1
å¾å°ç´¯å åä¿¡æ¯çå叿 ç大å°ï¼åå¼çæ
åµï¼é£ä¹updateæ´æ°æ ï¼åaddç´¯å æ ï¼åæ ·ç大å°ååæ ·çåæ å
³ç³»æå»ºã
1.1.2æ´æ°ç»ææ°ç»å»ºç«
ææ´æ°æ¦å¿µï¼ä¾å¦æ8个æ°ï¼æä»¬è¦æ1å°6çæ°é½åå°2ãé£ä¹å
ç1å°6æ¯å¦å®å
¨åæ¬8个æ°ï¼å¦æåæ¬ç´æ¥æ´æ°ã徿¾ç¶è¿é没æåæ¬ï¼è®°å½è¦æ´æ°1å°6ï¼ä¸å该任å¡ç»1å°4å5å°8ã1å°6å®å
¨åæ¬1å°4ï¼è®°å½å°lazyä¸ï¼ä¸åä¸åï¼5å°8没æåæ¬1å°6ï¼ç»§ç»ä¸åç»5å°6å7å°8ï¼5å°6è¢«åæ¬ï¼è®°å½å°lazyä¸åç»§ç»ä¸åï¼7å°8䏿¥å该任å¡
è¿ç§ææ´æ°æºå¶çæ¶é´å¤æåº¦ä¸ºO(logN)ï¼ç±äºä¸ä¸ªåºé´ç»è¿å·¦å³åæ ä¸åï¼åªä¼ç»è¿ä¸ä¸ªç»å¯¹è·¯å¾å°å¶åèç¹ï¼å
¶ä»èç¹é½ä¼è¢«æä½ã妿æä¸ªèç¹ææ°çä»»å¡è¿æ¥ï¼ä¼æä¹åæä½çä¿¡æ¯ä¸åç»å·¦å³å©å
对äºupdateæä½ï¼å¦æupdateæä½ç»è¿çä¿¡æ¯èç¹ä¸å卿任å¡ï¼é£ä¹è¯¥æ¬¡updateæä½ä¼åæ¶è¯¥èç¹çlazyï¼æ éä¸åï¼å 为ä¸åäºä¹ä¼ç»updateè¦çæï¼
```Java
public class Code01_SegmentTree {
public static class SegmentTree {
// arr[]为ååºåçä¿¡æ¯ä»0å¼å§ï¼ä½å¨arr鿝ä»1å¼å§ç
// sum[]模æçº¿æ®µæ ç»´æ¤åºé´å
// lazy[]ä¸ºç´¯å ææ°æ è®°
// change[]ä¸ºæ´æ°çå¼
// update[]ä¸ºæ´æ°æ
µææ è®°
private int MAXN;
private int[] arr;
// 4*arr.length()
private int[] sum;
// 4*arr.length()
private int[] lazy;
// 4*arr.length()
private int[] change;
// 4*arr.length()
private boolean[] update;
// æ ¹æ®int[] originæ¥åå§åæä»¬ç线段æ ç»æ
public SegmentTree(int[] origin) {
MAXN = origin.length + 1;
arr = new int[MAXN]; // arr[0] ä¸ç¨ ä»1å¼å§ä½¿ç¨
for (int i = 1; i < MAXN; i++) {
arr[i] = origin[i - 1];
}
// sumæ°ç»å¼è¾ç大尿¯åå§æ°ç»ç4å
sum = new int[MAXN << 2]; // ç¨æ¥æ¯æèè¡¥æ¦å¿µä¸ï¼æä¸ä¸ªèå´çç´¯å åä¿¡æ¯
lazy = new int[MAXN << 2]; // ç¨æ¥æ¯æèè¡¥æ¦å¿µä¸ï¼æä¸ä¸ªèå´æ²æå¾ä¸å³éççºå ä»»å
change = new int[MAXN << 2]; // ç¨æ¥æ¯æèè¡¥æ¦å¿µä¸ï¼æä¸ä¸ªèå´ææ²¡ææ´æ°æä½çä»»å¡
update = new boolean[MAXN << 2]; // ç¨æ¥æ¯æèè¡¥æ¦å¿µä¸ï¼æä¸ä¸ªèå´æ´æ°ä»»å¡ï¼æ´æ°æäºä»ä¹
}
// æ±æ»å½åä½ç½®rtçä¿¡æ¯ï¼ä¸ºå·¦å©åä¿¡æ¯å ä¸å³å©åä¿¡æ¯
private void pushUp(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
// ä¹åçï¼æææå¢å ï¼åææ´æ°ï¼ä»ç¶èå´ï¼åç»å·¦å³ä¸¤ä¸ªåèå´
// ååçç¥æ¯ä»ä¹
// lnè¡¨ç¤ºå·¦åæ å
ç´ ç»ç¹ä¸ªæ°ï¼rn表示å³åæ ç»ç¹ä¸ªæ°
private void pushDown(int rt, int ln, int rn) {
// é¦å
æ£æ¥ç¶äº²èå´ä¸ææ²¡æææ´æ°æä½
if (update[rt]) {
// ç¶èå´æææ´æ°æä½ï¼å·¦å³åèå´å°±æææ´æ°æä½
update[rt << 1] = true;
update[rt << 1 | 1] = true;
// å·¦å³åèå´çchange以ç¶äº²ååç为å
change[rt << 1] = change[rt];
change[rt << 1 | 1] = change[rt];
// å·¦å³åèå´çæä»»å¡å
¨é¨æ¸
空
lazy[rt << 1] = 0;
lazy[rt << 1 | 1] = 0;
// å·¦å³åèå´çç´¯å åå
¨é¨å为å½åç¶èç¹ä¸åçchangeä¹ä»¥å·¦å³å©åçèå´ä¸ªæ°
sum[rt << 1] = change[rt] * ln;
sum[rt << 1 | 1] = change[rt] * rn;
// ç¶èå´çæ´æ°ä»»å¡è¢«ååå°å·¦å³åèå´ï¼å½åç¶èå´çæ´æ°ä»»å¡æ¹ä¸ºfalse
update[rt] = false;
}
// 妿ä¸é¢çifä¹è¿å
¥ï¼è¯¥ifä¹è¿å
¥ï¼è¡¨ç¤ºä¹åçæææä½çæ´æ°å°ç°å¨è¿æ²¡æåçè¿æ°çæ´æ°ä½¿ä¹ä¸åï¼å´æ¥äºä¸ªaddä»»å¡
// æä»¥è¯¥èç¹å³æä½äºæ´æ°ä»»å¡ï¼åæä½ä¸ä¸ªaddä»»å¡ï¼æ¥ç忥äºä¸ä¸ªupdateä»»å¡ï¼æä»¥æ´æ°è¦å
ä¸åå°åèå´ï¼æ¥çè¦æå½åçaddä»»å¡ä¸åä¸å»
// 妿å½åèç¹çæä¿¡æ¯ä¸ä¸ºç©ºã
if (lazy[rt] != 0) {
// ä¸åç»å·¦å©å
lazy[rt << 1] += lazy[rt];
sum[rt << 1] += lazy[rt] * ln;
// ä¸åç»å³å©å
lazy[rt << 1 | 1] += lazy[rt];
sum[rt << 1 | 1] += lazy[rt] * rn;
// æ¸
空å½åèç¹çæä»»å¡ä¿¡æ¯
lazy[rt] = 0;
}
}
// å¨åå§åé¶æ®µï¼å
æsumæ°ç»ï¼å¡«å¥½
// å¨arr[l~r]èå´ä¸ï¼å»buildï¼1~Nï¼
// rt : è¿ä¸ªèå´å¨sumä¸ç䏿
public void build(int l, int r, int rt) {
if (l == r) {
sum[rt] = arr[l];
return;
}
// å¾å°lå°rçä¸é´ä½ç½®
int mid = (l + r) >> 1;
// lå°r左侧ï¼å¡«å
å°sumæ°ç»rt䏿 ç2åçä½ç½®ï¼å ä¸ºå¨æ°ç»ä¸å½åèç¹åå·¦å©åçå
³ç³»å¾å°
// éå½rtå·¦åºé´
build(l, mid, rt << 1);
// å³ä¾§ï¼å¡«å
å°2*rt+1çä½ç½®
// éå½rtå³åºé´
build(mid + 1, r, rt << 1 | 1);
pushUp(rt);
}
// æ´æ°æä½
public void update(int L, int R, int C, int l, int r, int rt) {
// å¦ææ´æ°ä»»å¡å½»åºè¦çå½åè¾¹ç
if (L <= l && r <= R) {
// å½åä½ç½®çupdateæ 记为true
update[rt] = true;
// å½åä½ç½®éè¦æ¹å为C, updateåchangeæé
使ç¨
change[rt] = C;
// å½åèç¹çç´¯å åä¿¡æ¯ï¼è¢«C * (r - l + 1)è¦çæ
sum[rt] = C * (r - l + 1);
// æ¸
空ä¹ååå¨è¯¥èç¹çæä»»å¡
lazy[rt] = 0;
return;
}
// å½åä»»å¡èº²ä¸æï¼æ æ³ææ´æ°ï¼è¦å¾ä¸å
int mid = (l + r) >> 1;
// ä¹åçï¼ææææ´æ°ï¼ä»ç¶èå´ï¼åç»å·¦å³ä¸¤ä¸ªåèå´
pushDown(rt, mid - l + 1, r - mid);
// æ´æ°ä»»å¡åç»å·¦å©å
if (L <= mid) {
update(L, R, C, l, mid, rt << 1);
}
// æ´æ°ä»»å¡åç»å³å©å
if (R > mid) {
update(L, R, C, mid + 1, r, rt << 1 | 1);
}
pushUp(rt);
}
// L..R -> ä»»å¡èå´ ,ææçå¼ç´¯å ä¸C
// l,r -> 表达çèå´
// rt å»åªæ¾lï¼rèå´ä¸çä¿¡æ¯
public void add(
int L, int R, int C,
int l, int r,
int rt) {
// ä»»å¡çèå´å½»åºè¦çäºï¼å½å表达çèå´ï¼æä½
if (L <= l && r <= R) {
// å½åä½ç½®çç´¯å åå ä¸C * (r - l + 1),çåäºä¸è¾¹èç¹é½å ä¸C,ç±äºè¢«æä½ï¼ä¸é¢èç¹å¹¶æ²¡æçæ£ææä¸addä¸ä¸ªC
sum[rt] += C * (r - l + 1);
// ä¹åæä½çä¿¡æ¯ï¼ä¾å¦ä¹å该èç¹å ä¸3ï¼åæ¥ä¸ä¸ªå ä¸7çä»»å¡ï¼é£ä¹æ¤æ¶lazt[rt]==10
lazy[rt] += C;
return;
}
// ä»»å¡å¹¶æ²¡ææl...rå
¨å
ä½
// è¦æå½åä»»å¡å¾ä¸å
// ä»»å¡ L, R æ²¡æææ¬èº«è¡¨è¾¾èå´ l,r å½»åºå
ä½
int mid = (l + r) >> 1; // l..mid (rt << 1) mid+1...r(rt << 1 | 1)
// ä¸åä¹å该èç¹æææçæä»»å¡å°å©åèç¹
pushDown(rt, mid - l + 1, r - mid);
// å·¦å©åæ¯å¦éè¦æ¥å°ä»»å¡
if (L <= mid) {
add(L, R, C, l, mid, rt << 1);
}
// å³å©åæ¯å¦éè¦æ¥å°ä»»å¡
if (R > mid) {
add(L, R, C, mid + 1, r, rt << 1 | 1);
}
// å·¦å³å©ååå®ä»»å¡åï¼ææ´æ°æçsumä¿¡æ¯
pushUp(rt);
}
// 1~6 ç´¯å 忝å¤å°ï¼ 1~8 rt
public long query(int L, int R, int l, int r, int rt) {
// ç´¯å ä»»å¡è¦çå½åèç¹èå´ï¼è¿åå½åèç¹èå´çç´¯å å
if (L <= l && r <= R) {
return sum[rt];
}
// 没è¦çå½åèç¹çèå´ï¼æ±æ»å·¦å³åèå´çç´¯å åï¼æ±æ»ç»å°å½åèç¹
int mid = (l + r) >> 1;
pushDown(rt, mid - l + 1, r - mid);
long ans = 0;
if (L <= mid) {
ans += query(L, R, l, mid, rt << 1);
}
if (R > mid) {
ans += query(L, R, mid + 1, r, rt << 1 | 1);
}
return ans;
}
}
// æ´åè§£æ³ï¼ç¨æ¥å对æ°å¨
public static class Right {
public int[] arr;
public Right(int[] origin) {
arr = new int[origin.length + 1];
// åä¸å±æ·è´ï¼arr[0]ä½ç½®åºå¼ä¸ç¨ï¼ä¸æ ä»1å¼å§
for (int i = 0; i < origin.length; i++) {
arr[i + 1] = origin[i];
}
}
public void update(int L, int R, int C) {
for (int i = L; i <= R; i++) {
arr[i] = C;
}
}
public void add(int L, int R, int C) {
for (int i = L; i <= R; i++) {
arr[i] += C;
}
}
public long query(int L, int R) {
long ans = 0;
for (int i = L; i <= R; i++) {
ans += arr[i];
}
return ans;
}
}
public static int[] genarateRandomArray(int len, int max) {
int size = (int) (Math.random() * len) + 1;
int[] origin = new int[size];
for (int i = 0; i < size; i++) {
origin[i] = (int) (Math.random() * max) - (int) (Math.random() * max);
}
return origin;
}
public static boolean test() {
int len = 100;
int max = 1000;
int testTimes = 5000;
int addOrUpdateTimes = 1000;
int queryTimes = 500;
for (int i = 0; i < testTimes; i++) {
int[] origin = genarateRandomArray(len, max);
SegmentTree seg = new SegmentTree(origin);
int S = 1;
int N = origin.length;
int root = 1;
seg.build(S, N, root);
Right rig = new Right(origin);
for (int j = 0; j < addOrUpdateTimes; j++) {
int num1 = (int) (Math.random() * N) + 1;
int num2 = (int) (Math.random() * N) + 1;
int L = Math.min(num1, num2);
int R = Math.max(num1, num2);
int C = (int) (Math.random() * max) - (int) (Math.random() * max);
if (Math.random() < 0.5) {
seg.add(L, R, C, S, N, root);
rig.add(L, R, C);
} else {
seg.update(L, R, C, S, N, root);
rig.update(L, R, C);
}
}
for (int k = 0; k < queryTimes; k++) {
int num1 = (int) (Math.random() * N) + 1;
int num2 = (int) (Math.random() * N) + 1;
int L = Math.min(num1, num2);
int R = Math.max(num1, num2);
long ans1 = seg.query(L, R, S, N, root);
long ans2 = rig.query(L, R);
if (ans1 != ans2) {
return false;
}
}
}
return true;
}
public static void main(String[] args) {
int[] origin = { 2, 1, 1, 2, 3, 4, 5 };
SegmentTree seg = new SegmentTree(origin);
int S = 1; // æ´ä¸ªåºé´çå¼å§ä½ç½®ï¼è§å®ä»1å¼å§ï¼ä¸ä»0å¼å§ -> åºå®
int N = origin.length; // æ´ä¸ªåºé´çç»æä½ç½®ï¼è§å®è½å°Nï¼ä¸æ¯N-1 -> åºå®
int root = 1; // æ´æ£µæ ç头èç¹ä½ç½®ï¼è§å®æ¯1ï¼ä¸æ¯0 -> åºå®
int L = 2; // æä½åºé´çå¼å§ä½ç½® -> å¯å
int R = 5; // æä½åºé´çç»æä½ç½® -> å¯å
int C = 4; // è¦å çæ°åæè
è¦æ´æ°çæ°å -> å¯å
// åºé´çæï¼å¿
é¡»å¨[S,N]æ´ä¸ªèå´ä¸build
seg.build(S, N, root);
// åºé´ä¿®æ¹ï¼å¯ä»¥æ¹åLãRåCçå¼ï¼å
¶ä»å¼ä¸å¯æ¹å
seg.add(L, R, C, S, N, root);
// åºé´æ´æ°ï¼å¯ä»¥æ¹åLãRåCçå¼ï¼å
¶ä»å¼ä¸å¯æ¹å
seg.update(L, R, C, S, N, root);
// åºé´æ¥è¯¢ï¼å¯ä»¥æ¹åLåRçå¼ï¼å
¶ä»å¼ä¸å¯æ¹å
long sum = seg.query(L, R, S, N, root);
System.out.println(sum);
System.out.println("对æ°å¨æµè¯å¼å§...");
System.out.println("æµè¯ç»æ : " + (test() ? "éè¿" : "æªéè¿"));
}
}
```
1.2 çº¿æ®µæ æ¡ä¾å®æ
æ³è±¡ä¸ä¸æ åçä¿ç½æ¯æ¹å游æï¼Xè½´æ¯ç§¯æ¨æç»ä¸è½å°åºç轴线
ä¸é¢æ¯è¿ä¸ªæ¸¸æçç®åçï¼
1ï¼åªä¼ä¸è½æ£æ¹å½¢ç§¯æ¨
2ï¼[a,b] -> 代表ä¸ä¸ªè¾¹é¿ä¸ºbçæ£æ¹å½¢ç§¯æ¨ï¼ç§¯æ¨å·¦è¾¹ç¼æ²¿çX = aè¿æ¡çº¿ä»ä¸æ¹æè½
3ï¼è®¤ä¸ºæ´ä¸ªXè½´é½å¯è½æ¥ä½ç§¯æ¨ï¼ä¹å°±æ¯è¯´ç®åçæ¸¸ææ¯æ²¡ææ´ä½çå·¦å³è¾¹çç
4ï¼æ²¡ææ´ä½çå·¦å³è¾¹çï¼æä»¥ç®åçæ¸¸æä¸ä¼æ¶é¤ç§¯æ¨ï¼å 为ä¸ä¼æåªä¸å±è¢«å¡«æ»¡ã
ç»å®ä¸ä¸ªN*2çäºç»´æ°ç»matrixï¼å¯ä»¥ä»£è¡¨N个积æ¨ä¾æ¬¡æè½ï¼
è¿åæ¯ä¸æ¬¡æè½ä¹åçæå¤§é«åº¦
> 线段æ åç»æï¼æ¯æ¶éèå´ç´¯å åï¼æ¬é¢æ¯èå´ä¸æ¶éæå¤§é«åº¦å½ææ¶éçä¿¡æ¯
```Java
public class Code02_FallingSquares {
// 0ä½ç½®ä¸ç¨ï¼ä»1å¼å§
public static class SegmentTree {
private int[] max;
private int[] change;
private boolean[] update;
public SegmentTree(int size) {
int N = size + 1;
max = new int[N << 2];
change = new int[N << 2];
update = new boolean[N << 2];
}
private void pushUp(int rt) {
max[rt] = Math.max(max[rt << 1], max[rt << 1 | 1]);
}
// lnè¡¨ç¤ºå·¦åæ å
ç´ ç»ç¹ä¸ªæ°ï¼rn表示å³åæ ç»ç¹ä¸ªæ°
private void pushDown(int rt, int ln, int rn) {
if (update[rt]) {
update[rt << 1] = true;
update[rt << 1 | 1] = true;
change[rt << 1] = change[rt];
change[rt << 1 | 1] = change[rt];
max[rt << 1] = change[rt];
max[rt << 1 | 1] = change[rt];
update[rt] = false;
}
}
public void update(int L, int R, int C, int l, int r, int rt) {
if (L <= l && r <= R) {
update[rt] = true;
change[rt] = C;
max[rt] = C;
return;
}
int mid = (l + r) >> 1;
pushDown(rt, mid - l + 1, r - mid);
if (L <= mid) {
update(L, R, C, l, mid, rt << 1);
}
if (R > mid) {
update(L, R, C, mid + 1, r, rt << 1 | 1);
}
pushUp(rt);
}
public int query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
return max[rt];
}
int mid = (l + r) >> 1;
pushDown(rt, mid - l + 1, r - mid);
int left = 0;
int right = 0;
if (L <= mid) {
left = query(L, R, l, mid, rt << 1);
}
if (R > mid) {
right = query(L, R, mid + 1, r, rt << 1 | 1);
}
return Math.max(left, right);
}
}
// positions
// [2,7] -> 表示ä½ç½®ä»2å¼å§ï¼è¾¹é¿ä¸º7çæ¹åï¼è½ä¸çxè½´èå´ä¸º2å°8ï¼ä¸å
æ¬9æ¯å 为ä¸ä¸ä¸ªä½ç½®ä¸º9å¯ä»¥è½å¾ä¸æ¥ï¼ 2 , 8
// [3, 10] -> 3, 12
//
// ç¨treeSetå离æ£åï¼é¿å
å¤ç³è¯·ç©ºé´
public HashMap index(int[][] positions) {
TreeSet pos = new TreeSet<>();
for (int[] arr : positions) {
pos.add(arr[0]);
pos.add(arr[0] + arr[1] - 1);
}
HashMap map = new HashMap<>();
int count = 0;
for (Integer index : pos) {
map.put(index, ++count);
}
return map;
}
public List fallingSquares(int[][] positions) {
HashMap map = index(positions);
// 100 -> 1 306 -> 2 403 -> 3
// [100,403] 1~3
int N = map.size(); // 1 ~ N
SegmentTree segmentTree = new SegmentTree(N);
int max = 0;
List res = new ArrayList<>();
// æ¯è½ä¸ä¸ªæ£æ¹å½¢ï¼æ¶éä¸ä¸ï¼ææä¸è¥¿ç»æçå¾åï¼æé«é«åº¦æ¯ä»ä¹
for (int[] arr : positions) {
int L = map.get(arr[0]);
int R = map.get(arr[0] + arr[1] - 1);
int height = segmentTree.query(L, R, 1, N, 1) + arr[1];
max = Math.max(max, height);
res.add(max);
segmentTree.update(L, R, height, 1, N, 1);
}
return res;
}
}
```
æ¬é¢ä¸ºleetCodeåé¢ï¼https://leetcode.com/problems/falling-squares/
1.3 ä»ä¹æ ·çé¢ç®å¯ä»¥ç¨çº¿æ®µæ æ¥è§£å³ï¼
åºé´èå´ä¸ï¼ç»ä¸å¢å ï¼æè
ç»ä¸æ´æ°ä¸ä¸ªå¼ã大èå´ä¿¡æ¯å¯ä»¥åªç±å·¦ãå³ä¸¤ä¾§ä¿¡æ¯å å·¥åºï¼
èä¸å¿
éåå·¦å³ä¸¤ä¸ªåèå´çå
·ä½ç¶åµ