HDU1199 離散化線段樹

2022-05-02 21:45:12 字數 1995 閱讀 1551

題目大意: 一段長度未知的線段,一種操作:a b c ,表示區間[a,b]要塗的顏色,c=w塗白色,c=b塗黑色,問你最長的白色區間段時多長。

解題思路:

就快去南京邀請賽了,最近做題超沒狀態,cf rating一直掉,這麼簡單的線段樹離散化居然搞了我乙個晚上,糾結。

開始用線段樹區間合併的方法做,wa到死,換個寫法,又wa到死,沒處理好邊界問題。

這題用普通的離散化沒用,藐視這種離散化第一次遇見,以前的離散化要麼就是點化點,線段化點,這題不一樣,是點化線段,一不小心處理不好就wa了。

點化線段我利用的是左閉右開,即對於一段區間[a,b],轉化成區間[a,b+1),接下來就是把所有端點當做簡單的離散化處理了,然後運用線段樹成段更新操作處理就好了。

view code

1 #include 2 #include 3 #include 4 #include 5

using

namespace

std;67

#define lz 2*u,l,mid

8#define rz 2*u+1,mid,r //

/注意:這裡是點化為線段(左閉右開)

9const

int maxn=5555;10

const

int oo=0x3fffffff;11

int flag[4*maxn], color[maxn];

12int

x[maxn];

1314

struct

node

1518 node(int lx_, int rx_, int

s_)19

22}line[maxn];

2324

void push_down(int u, int l, int

r)2532}

3334

void update(int u, int l, int r, int tl, int tr, int

c)35

42push_down(u,l,r);

43int mid=(l+r)>>1;44

if(tr<=mid) update(lz,tl,tr,c);

45else

if(tl>mid) update(rz,tl,tr,c);

46else

4751}52

53void query(int u, int l, int

r)54

61push_down(u,l,r);

62int mid=(l+r)>>1;63

query(lz);

64query(rz);65}

6667

int find(int tmp, int

n)6877}

7879

intmain()

8095 sort(x+1,x+num+1

);96

int ep=1;97

for(int i=2; i<=num; i++)

98if(x[ep]!=x[i]) x[++ep]=x[i];

99 memset(color,0,sizeof

(color));

100 memset(flag,-1,sizeof

(flag));

101for(int i=0; i)

102107 query(1,1,ep+1

);108

int s=0, d=0

, ts, td;

109for(int i=1; i<=ep; i++)

110121

}122

if(s==d) puts("

oh, my god");

123else printf("

%d %d\n

",s, d-1

);124

}125

return0;

126 }

HDU1199 動態線段樹 離散化

附動態線段樹ac 在乙個全部塗黑色的條子上塗上一些白色或黑色的片段,問最大白色片段。僅僅從線段樹維護節點的角度上來看很簡單,維護最大白色片段,左邊最大白色片段,右邊最大白色片段就好了。由於條子的長度長達1 int max 採用離散化,或者像我一樣失了智去用動態線段樹的方法,也能ac include ...

HDU 3333 線段樹 離散化

只查詢區間不同的數的和 思路好題 對查詢離線 不斷的往每個位置插值 並把前面位置的值置為0 每查到乙個右端點 查詢一下 等價操作的轉換 離散化一下 include define mem a,b memset a,b,sizeof a define lson root 1 define rson ro...

離散化 線段樹

題目 分析 每次1操作會往序列底加first個second,first 和 second 都是最大1e9的資料,每次2操作詢問序列中第first到第second個數的和 一開始就感覺有點像線段樹,輸入資料太大我們可以離線處理把資料離散化下,然後扔到線段樹上,維護兩個陣列 sum 區間數的值的和 nu...