hdu1542(線段樹 掃瞄線)

2022-05-13 21:22:37 字數 3236 閱讀 8969

題目連線:

又看到了幾個月前做的題,感覺那時候就是個sb

也怪自己剛開始沒搞清楚線段樹,,瞎摸索

用連續線段樹很好理解這個題,之前的**稍微改了一下就好理解多了

1 #include2 #include3 #include4

#define lson l,m,rt<<1

5#define rson m,r,rt<<1|1

6using

namespace

std;

7const

int maxn=210; //

需要離散的x座標數

8int cnt[maxn<<2]; //

標記該線段是否被選

9double sum[maxn<<2]; //

被選擇的部分線段總長度

10double x[maxn<<2]; //

離散化11

struct

seg12

17 seg(double l,double r,double h,int

s):l(l),r(r),h(h),s(s){}

18bool

operator

< (const seg &cmp) const

1922

}ss[maxn];

2324

void pushup(int rt,int l,int

r)25

3031

void update(int l,int r,int c,int l,int r,int

rt)32

39int m=(l+r)>>1;40

if(l

41if(m

42pushup(rt,l,r);43}

44int bin(double key,int n,double

x)45

54return -1;55

}56intmain()

5771 sort(x,x+m);

72 sort(ss,ss+m);

73//

離散化74

int k=1;75

for(int i=1;i)

76if(x[i]!=x[i-1]) x[k++]=x[i];

7778 memset(cnt,0,sizeof

(cnt));

79 memset(sum,0,sizeof

(sum));

80double ans=0;81

for(int i=0;i1;i++) //

最上面的線段不用處理

8288 printf("

test case #%d\ntotal explored area: %.2lf\n\n

",++cas,ans);89}

90return0;

91 }

view code

下面的可以不看了。。。。。。

看了很久別人的**才理解。。

最重要的一點是要搞清楚線段樹節點的意義:節點記錄的是 該節點到後乙個節點之間的線段長度

從0開始計數

例如: 節點0-0,記錄的是第0個點到第1個點之間線段的長度,即第一條線段的長度

節點1-2,記錄的是第1個點到第3個點之間線段的長度,即第2和第3條線段的長度

關於線段樹節點的理解,不管是要維護什麼資訊,必須是乙個點代表乙個資訊(模擬最開始學習時維護的陣列,乙個下標代表乙個需要維護的值)

每個節點(乙個區間)中包含多個點,葉子含乙個點

所以這裡用線段的左端點代表這條線段,而不能用區間表示線段

1 #include2 #include3 #include4

#define lson l,m,rt<<1

5#define rson m+1,r,rt<<1|1

6using

namespace

std;

7const

int maxn=210; //

需要離散的x座標數

8int cnt[maxn<<2]; //

標記該線段是否被選

9double sum[maxn<<2]; //

被選擇的部分線段總長度

10double x[maxn<<2]; //

離散化11

struct

seg12

17 seg(double l,double r,double h,int

s):l(l),r(r),h(h),s(s){}

18bool

operator

< (const seg &cmp) const

1922

}ss[maxn];

2324

void pushup(int rt,int l,int

r)25

3031

void update(int l,int r,int c,int l,int r,int

rt)32

39int m=(l+r)>>1;40

if(l<=m) update(l,r,c,lson);

41if(m

42pushup(rt,l,r);43}

44int bin(double key,int n,double

x)45

54return -1;55

}56intmain()

5771 sort(x,x+m);

72 sort(ss,ss+m);

73//

離散化74

int k=1

;

75for(int i=1;i)

76if(x[i]!=x[i-1]) x[k++]=x[i];

7778 memset(cnt,0,sizeof

(cnt));

79 memset(sum,0,sizeof

(sum));

80double ans=0;81

for(int i=0;i1;i++) //

最上面的線段不用處理

8288 printf("

test case #%d\ntotal explored area: %.2lf\n\n

",++cas,ans);89}

90return0;

91 }

hdu1542(線段樹 掃瞄線)

裸的掃瞄線,學習掃瞄線的題目。具體掃瞄線的原理我不講了,我是看大神們的部落格懂得,就算寫也沒大神屌。下面我給出我的 裡面的注釋是我認為比較重要的地方 include include include includeusing namespace std const int max 210 int n ...

hdu 1542 掃瞄線 線段樹

題目大意 求矩形面積的並 思路 按y軸排序,然後將x投影到線段樹上做乙個線段覆蓋問題即可 注意 為了避免重複,線段座標右端點是開區間,更新時需要加上1 include include include include include define fo i,a,b for int i a i b i ...

HDU 1542 掃瞄線 線段樹優化

有些需要說明的地方 以前寫線段樹時線段樹的每個葉節點為乙個數字,代表乙個區域 7 代表第七個單位長度區域 本題不同在於,最小單位區域必須有兩點代表 2 3 代表從2到3 的乙個區域 上篇掃瞄線演算法複雜度為o n 2 本題用離散化法加線段樹優化為nlog n include include incl...