青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

oyjpArt ACM/ICPC算法程序設計空間

// I am new in programming, welcome to my blog
I am oyjpart(alpc12, 四城)
posts - 224, comments - 694, trackbacks - 0, articles - 6

Picture
Time Limit:2000MS? Memory Limit:10000K
Total Submit:742 Accepted:411

Description
A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wall. Their sides are all vertical or horizontal. Each rectangle can be partially or totally covered by the others. The length of the boundary of the union of all rectangles is called the perimeter.

Write a program to calculate the perimeter. An example with 7 rectangles is shown in Figure 1.


The corresponding boundary is the whole set of line segments drawn in Figure 2.

The vertices of all rectangles have integer coordinates.

Input
Your program is to read from standard input. The first line contains the number of rectangles pasted on the wall. In each of the subsequent lines, one can find the integer coordinates of the lower left vertex and the upper right vertex of each rectangle. The values of those coordinates are given as ordered pairs consisting of an x-coordinate followed by a y-coordinate.

0 <= number of rectangles < 5000
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.

Output
Your program is to write to standard output. The output must contain a single line with a non-negative integer which corresponds to the perimeter for the input rectangles.

Sample Input

7
-15 0 5 10
-5 8 20 25
15 -4 24 14
0 -6 16 4
2 15 10 22
30 10 36 20
34 0 40 16

Sample Output

228

Source
IOI 1998

做這道題之前我用線段樹的結構過了幾個題目 效果沒有我想象的好
但是這道題明顯就出了差距 直接離散化與用線段樹來做效果差了有將近10倍!




線段樹的基本應用:請參考這篇文章

http://www.shnenglu.com/sicheng/archive/2006/11/24/15640.html

這里我們再加上測度與連續段的作用:

(一)、?? 測度

由于線段樹結構遞歸定義,其測度也可以遞歸定義。增加數據域 Lines_Tree.M 表示以該結點為根的子樹的測度。 M 取值如下:

?

?

???????? a[j] – a[i] ?? 該結點 Count>0

M? =??? 0???????? ? 該結點為葉結點且 Count=0

???????? Leftchild .M + Rightchild .M ? 該結點為內部結點且 Count=0

?

據此,可以用 Lines_Tree.UpData 來動態地維護 Lines_Tree.M UpData 在每一次執行 Insert Delete 之后執行。定義如下:

Procedure? Lines_Tree.UpData

1??????? if? count? >? 0

2??????? ??then? M? ? ? a[j]? ? [i]????? { 蓋滿區間,測度為 a[j] – a[i]}

3??????? ??else? if? j? -? i? =? 1 ????????{ 是否葉結點 }

4??????? ??????????then? M? ? ? 0 ??????{ 該結點是葉結點 }

5??????? ??????????else? M? ? ? Leftchild .M? +? Rightchild .M
????????????????????????????????????????? ?{
內部結點 }

UpData 的復雜度為 O(1) ,則用 UpData 來動態維護測度后執行根結點的 Insert Delete 的復雜度仍為 O(logN)

(二)、?? 連續段數

這里的連續段數指的是區間的并可以分解為多少個獨立的區間。如 [1 2] [23] [5 6] 可以分解為兩個區間 [1 3] [5 6] ,則連續段數為 2 。增加一個數據域 Lines_Tree.line 表示該結點的連續段數。 Line 的討論比較復雜,內部結點不能簡單地將左右孩子的 Line 相加。所以再增加 Lines_Tree.lbd Lines_Tree.rbd 域。定義如下:

?

???????? 1??? 左端點 I 被描述區間蓋到

lbd? =?

???????? 0? ?? 左端點 I 不被描述區間蓋到

?

???????? 1???? 右端點 J 被描述區間蓋到

rbd? =?

??????? ?0 ???? 右端點 J 不被描述區間蓋到

?

lbd rbd 的實現:

????????? 1? 該結點 count > 0

lbd? =??? 0? 該結點是葉結點且 count = 0

????????? leftchild .lbd??? 該結點是內部結點且 Count=0

? ????????1? 該結點 count > 0

rbd? =??? 0? 該結點是葉結點且 count = 0

????????? rightchild .rbd?? 該結點是內部結點且 Count=0

有了 lbd rbd Line 域就可以定義了:

??????? 1? 該結點 count > 0

Line =?? 0? 該結點是葉結點且 count = 0

??????? ?Leftchild .Line? +? Rightchild .Line? -? 1
????????
當該結點是內部結點且 Count=0 Leftchild .rbd = 1 Rightchild .lbd = 1

???????? Leftchild .Line? +? Rightchild .Line??
??? ?????
當該結點是內部結點且 Count=0 Leftchild .rbd Rightchild .lbd 不都為 1

?

據此,可以定義 UpData’ 動態地維護 Line 域。與 UpData 相似, UpData’ 也在每一次執行 Insert Delete 后執行。定義如下:

Procedure? Lines_Tree.UpData’

1??????? if? count? >? 0 ??????????{ 是否蓋滿結點表示的區間 }

2??????? ??then? lbd?? ? ? 1

3??????? ???????rbd?? ? ? 1

4??????? ???????Line? ? ? 1

5??????? ??else? if? ?j? -? i? =? 1???? { 是否為葉結點 }

6??????? ??????????then? lbd?? ? ? 0?? { 進行到這一步,如果為葉結點,
??????????????????????????????????????????????? count = 0}

7??????? ????????????????rbd? ? ? 0

8??????? ????????????????line? ? ? 0

9??????? ??????????else? line? ? ?? Leftchild .line? +? Rightchild .line? -?

????????????????????????????? Leftchild .rbd * Rightchild .lbd

{ 用乘法確定 Leftchild .rbd Rightchild .lbd 是否同時為 1}

?

于是我按下面的步驟重寫了程序:

1.??????? 以矩形頂點坐標切割平面,實現橫縱坐標的離散化并建立映射 X_Map Y_Map

2.??????? 事件排序

3.??????? Root.Build(1, N*2)

4.??????? Nowm??? ? ? 0

5.??????? NowLine? ? ? 0

6.??????? Ans????? ? ? 0

7.??????? for?? I? ? ? 1? to? 事件的最大編號

8.??????? ??do?? if? I 是插入事件

9.??????? ??????????then? Root.Insert(Y_Map.Coord[ 事件線段頂點 1]
???????????????????????? Y_Map.Coord[
事件線段頂點 2])

10.??? ??????????else? Root.Delete(Y_Map.Coord[ 事件線段頂點 1]
?????????????????? ? ??????Y_Map.Coord[
事件線段頂點 2])

11.??? ????????nowM??? ? ? Root.M

12.??? ????????nowLine? ? ? Root.Line

13.??? ????? ???ans??? ? ? ans? +? lastLine * 2 * (X_Map[I] – Y_Map[I-1])

14.??? ????????ans????? ? ? ans? +? |nowM – lastM|

15.??? ????????lasM???? ? ? nowM

16.??? ????????lastLine?? ? ? nowLine

參考論文《IOI98試題PICTURE談起 陳宏

#include? < stdio.h >
#include?
< stdlib.h >

const ? int ?maxn? = ? 5010 ;
// 寫一個線段樹的過程
struct ?Lines_tree
{
????Lines_tree?
* ?lchild,? * ?rchild;
????
int ?m;? // 測度
???? int ?cnt;??? // count
???? int ?lines;? // 連續段數
???? int ?lbd,?rbd;? // 左右端點是否被覆蓋?
???? int ?f,?r;? // 左右端點
}
;
Lines_tree
* ?root;
struct ?rec { int ?x,?y,?x1,?y1;} r[maxn];
struct ?Line
{
????
int ?x,?y1,?y2; int ?sign;
????Line(
int ?a,? int ?b,? int ?c, int ?d):x(a),?y1(b),?y2(c),?sign(d) {}
????Line(
void ):x( 0 ),y1( 0 ),y2( 0 ),sign( 0 ) {} ?
}
line[ 2 * maxn + 10 ];
int ?nr;
int ?ans;

void ?make_tree( int ?a,? int ?b,?Lines_tree * ?node)
{
????node
-> lines? = ? 0 ;?node -> m? = ? 0 ;?node -> cnt? = ? 0 ;
????node?
-> ?lbd? = ? 0 ;?node? -> ?rbd? = ? 0 ;
????node
-> lchild? = ?NULL;?node -> rchild? = ?NULL;
????node
-> f? = ?a;?node -> r? = ?b;
????
if (b - a > 1 )
????
{
????????node
-> lchild? = ? new ?Lines_tree;
????????make_tree(a,?(a
+ b) / 2 ,?node -> lchild);
????????node
-> rchild? = ? new ?Lines_tree;
????????make_tree((a
+ b) / 2 ,?b,?node -> rchild);
????}

}


void ?make( int ?a,? int ?b)
{
?????root?
= ? new ?Lines_tree;
?????make_tree(a,?b,?root);
}


void ?update(Lines_tree? * ?now)??? // lbd,?rbd,?m的計算都在這個里面!
{
????
if (now -> cnt > 0 )?now -> m? = ?now -> r - now -> f;
????
else ? if (now -> r == now -> f + 1 )?now -> m? = ? 0 ;
????
else ?now -> m? = ?now -> lchild -> m? + ?now -> rchild -> m;
}


void ?update2(Lines_tree * ?now)
{
????
if (now -> cnt > 0 )? {?now -> lbd? = ? 1 ;?now -> rbd? = ? 1 ;?now -> lines? = ? 1 ;?}
????
else ? if (now -> f + 1 == now -> r)? {now -> lbd? = ? 0 ;?now -> rbd? = ? 0 ;?now -> lines? = ? 0 ;}
????
else
????
{
????????now
-> lbd? = ?now -> lchild -> lbd;?now -> rbd? = ?now -> rchild -> rbd;
????????now
-> lines? = ?now -> lchild -> lines + now -> rchild -> lines? - ?now -> lchild -> rbd * now -> rchild -> lbd;
????}

}


void ?insert( int ?a,? int ?b,?Lines_tree? * ?now)
{
????
if (a <= now -> f? && ?b >= now -> r)
????????now
-> cnt ++ ;
????
if (now -> r - now -> f > 1 )
????
{
????????
if (a < (now -> f + now -> r) / 2 )????insert(a,?b,?now -> lchild);
????????
if (b > (now -> f + now -> r) / 2 )????insert(a,?b,?now -> rchild);
????}

????update(now);
????update2(now);
}


void ?del( int ?a,? int ?b,?Lines_tree? * ?now)
{
????
if (a <= now -> f? && ?b >= now -> f)
????
{
????????
if (a == now -> f)?now -> lbd? = ? 0 ;
????????
if (b == now -> r)?now -> rbd? = ? 0 ;
????????now
-> cnt -- ;
????}

????
if (now -> r - now -> f > 1 )
????
{
????????
if (a < (now -> f + now -> r) / 2 )????del(a,?b,?now -> lchild);
????????
if (b > (now -> f + now -> r) / 2 )????del(a,?b,?now -> rchild);
????}

????update(now);
????update2(now);
}


int ?cmp( const ? void ? * ?a,? const ? void ? * ?b)
{
????
return ?( * (Line * )a).x? - ?( * (Line * )b).x;??? // 這里不要寫成->
}


void ?init()
{
????
// initiation
????
// input
???? int ?i;
????scanf(
" %d " ,? & nr);
????
for (i = 0 ;?i < nr;?i ++ )
????
{
????????scanf(
" %d%d%d%d " ,? & r[i].x,? & r[i].y,? & r[i].x1,? & r[i].y1);
????????line[
2 * i]? = ?Line(r[i].x,?r[i].y,?r[i].y1,? 0 );
????????line[
2 * i + 1 ]? = ?Line(r[i].x1,?r[i].y,?r[i].y1,? 1 );
????}
????????
????qsort(line,?nr
* 2 ,? sizeof (line[ 0 ]),?cmp);
????
// pretreatment
}


void ?work()
{
????
int ?nowM? = ? 0 ;
????
int ?nowLine? = ? 0 ;
????
int ?lastM? = ? 0 ;
????
int ?lastLine? = ? 0 ;
????
int ?i;
????
for (i = 0 ;?i < nr * 2 ;?i ++ )
????
{
????????
if (line[i].sign == 0 )
????????????insert(line[i].y1,?line[i].y2,?root);
????????
else ?del(line[i].y1,?line[i].y2,?root);
????????nowM?
= ?root -> m;
????????nowLine?
= ?root -> lines;
????????ans?
+= ?lastLine? * ? 2 ? * ?(line[i].x - line[i - 1 ].x);
????????ans?
+= ?abs(nowM - lastM);
????????lastM?
= ?nowM;
????????lastLine?
= ?nowLine;
????}

}


void ?output()
{
????printf(
" %d\n " ,?ans);
}


int ?main()
{
// ????freopen("t.in",?"r",?stdin);
????make( - 10000 ,? 10000 );
????init();
????work();
????output();
????
return ? 0 ;
}

Feedback

# re: 線段樹測度與連續斷的應用 on IOI98 pictures  回復  更多評論   

2007-04-07 01:01 by
void del( int a, int b, Lines_tree * now)
{
if (a <= now -> f && b >= now -> f)


這個是不是有問題?
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            乱人伦精品视频在线观看| 亚洲精选在线观看| 久久www免费人成看片高清| 亚洲一级高清| 国产亚洲成年网址在线观看| 欧美亚洲一区二区三区| 午夜精品www| 影音先锋中文字幕一区| 免费中文日韩| 欧美日韩999| 欧美一区午夜视频在线观看| 午夜在线成人av| 在线观看日韩欧美| 亚洲欧洲日韩女同| 国产精品国内视频| 久久久亚洲影院你懂的| 欧美电影美腿模特1979在线看| 一区二区三区毛片| 午夜精品久久久久| 日韩写真视频在线观看| 亚洲一区二区在线| 亚洲人精品午夜| 亚洲在线播放| 亚洲精品亚洲人成人网| 一区二区三区国产精品| 黄色成人在线免费| 一区二区免费看| 亚洲成人自拍视频| 亚洲午夜一区二区| 亚洲黄色影院| 香蕉久久精品日日躁夜夜躁| 亚洲国产高清在线观看视频| 亚洲午夜激情免费视频| 亚洲国产三级在线| 欧美在线|欧美| 亚洲综合三区| 欧美二区在线播放| 久久婷婷麻豆| 国产毛片一区二区| 99香蕉国产精品偷在线观看| 国产女人精品视频| 一区二区三区精品国产| 亚洲福利小视频| 欧美怡红院视频| 亚洲欧美日产图| 欧美欧美午夜aⅴ在线观看| 老司机午夜精品视频| 国产精自产拍久久久久久| 亚洲精品欧美极品| 亚洲乱码国产乱码精品精天堂| 亚洲欧美在线另类| 午夜精品久久久久久久久久久| 欧美激情一区在线观看| 欧美激情影音先锋| 亚洲第一黄色| 另类春色校园亚洲| 免费不卡欧美自拍视频| 国产日韩精品电影| 先锋影音一区二区三区| 亚洲欧美国产va在线影院| 欧美日韩国产免费观看| 亚洲高清视频在线| 亚洲麻豆视频| 欧美韩日精品| 亚洲伦理在线观看| 亚洲一二三区视频在线观看| 欧美福利一区| 亚洲另类在线视频| 亚洲尤物视频在线| 国产精品一区二区三区成人| 一区二区三区精品在线| 亚洲欧美国产精品桃花| 国产精品入口66mio| 午夜一区二区三视频在线观看 | 欧美在线亚洲| 久久影音先锋| 91久久精品网| 欧美日韩中文在线| 亚洲欧美美女| 麻豆av福利av久久av| 黄色一区三区| 欧美精品在线免费播放| 亚洲精品欧美极品| 欧美在线精品免播放器视频| 国产亚洲欧美一区在线观看| 久久99伊人| 亚洲激情图片小说视频| 一区二区三区日韩欧美精品| 国产精品久久99| 久久久高清一区二区三区| 亚洲成在人线av| 午夜国产精品视频| 在线精品国产欧美| 欧美日韩在线精品| 欧美一区观看| 亚洲精选一区| 久久亚洲影音av资源网| 亚洲人成人一区二区三区| 欧美日一区二区三区在线观看国产免| 亚洲一区二区高清| 欧美大香线蕉线伊人久久国产精品| 亚洲精品乱码久久久久| 国产伦精品一区二区三| 免费在线观看一区二区| 亚洲一区精品电影| 亚洲国产成人av好男人在线观看| 午夜精品久久久久影视 | 欧美精品久久久久久| 欧美亚洲免费电影| 日韩小视频在线观看| 美乳少妇欧美精品| 欧美一区二区日韩一区二区| 最新亚洲一区| 精品成人国产| 国产精品一页| 国产精品第2页| 免费在线成人av| 久久久久久久久久久一区 | 日韩午夜在线播放| 亚洲国产精品成人| 久久久亚洲成人| 午夜精品www| 一本久久综合亚洲鲁鲁五月天| 国产一级揄自揄精品视频| 国产精品a级| 欧美日韩国产a| 欧美成人午夜激情在线| 久久久久久9| 久久精品一区二区三区不卡牛牛| 一区二区免费在线视频| 亚洲精品国偷自产在线99热| 欧美成人资源| 麻豆精品视频在线| 老司机一区二区| 久久在线免费视频| 久久午夜国产精品| 久久裸体艺术| 欧美+亚洲+精品+三区| 久久久国产亚洲精品| 欧美一区二区私人影院日本 | 久久免费精品视频| 久久久久国产精品厨房| 欧美专区中文字幕| 久久久www| 麻豆成人综合网| 欧美激情第五页| 亚洲激情六月丁香| 亚洲人屁股眼子交8| 亚洲精品美女久久7777777| 亚洲精品少妇| 一区二区av在线| 亚洲欧美日韩一区二区三区在线观看| 亚洲一区在线视频| 欧美一区二区视频免费观看| 久久国产精品72免费观看| 久久久久成人精品| 老司机aⅴ在线精品导航| 毛片av中文字幕一区二区| 欧美成人在线免费视频| 欧美理论电影网| 国产女人18毛片水18精品| 国产深夜精品福利| 亚洲国产免费| 宅男精品视频| 久久精品在线免费观看| 免费成人黄色av| 99国产精品一区| 久久狠狠婷婷| 欧美日韩国内自拍| 国产视频亚洲精品| 亚洲国产一区二区三区高清 | 亚洲国产一成人久久精品| 亚洲性感美女99在线| 久久久久网站| 亚洲黄页视频免费观看| 亚洲一区二区三区免费视频| 久久精品国产99精品国产亚洲性色| 欧美 亚欧 日韩视频在线| 欧美日韩午夜| 激情综合电影网| 亚洲在线网站| 欧美激情亚洲综合一区| 亚洲在线不卡| 欧美激情第三页| 国产在线欧美日韩| 亚洲视频综合在线| 欧美a级片网站| 亚洲欧美在线一区二区| 欧美激情二区三区| 精品成人a区在线观看| 亚洲自拍电影| 91久久综合亚洲鲁鲁五月天| 亚洲一区二区在| 欧美亚州一区二区三区| 最新日韩在线| 欧美激情一区二区三级高清视频| 亚洲免费在线播放| 国产精品美女www爽爽爽| 亚洲美洲欧洲综合国产一区| 久久综合网络一区二区|