題目大意: 一段長度未知的線段,一種操作: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 5using
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...