走査線セグメントツリー+
そして、矩形領域
前に書かれた長方形の境界線と
同じまたは長方形周縁、矩形断面アウト処理の各側面と垂直エッジに
複数のセクションに垂直面と全エッジ
メンテナンス間隔の長さは、セグメントツリーによって覆われています
その後、走査線およびボトムアップからのスキャンを続け、横方向のエッジをスキャン
上書きセグメントツリーのこれらのセクションの下部矩形断面を走査し、情報を更新します
矩形の上辺をスキャンするとき、これらのセクションをカバーする期間を除去することができます
そして、ときにのみ統計長方形の周囲と異なった答え
答えは2本の走査線の長さによってカバーされる全範囲の高さの電流差です*
#include <iostreamの> する#include <アルゴリズム> の#include <地図> の#include <cstdioを> の#define INF(INT)1E9 使用 名前空間STDを、 int型最後に、TOT、K、W、N。 二重 C [ 10000 ]、ANS。 ダブル S [ 10000 ]; マップ < ダブル、int型 > ID; 構造体ノード { ダブル、B、C、D。 } P [ 5100 ]。 構造体ツリー { int型のL、R、合計。 ダブル LEN; } SH [ 100000 ]。 構造体のエッジ { int型のL、R、種類; ダブルNUM; } [ 11000 ]。 BOOL CMP(辺A、辺B) { リターン(a.num <b.num ||(a.num == b.num && a.kind> b.kind))。 } ボイド押し上げ(INT X) { 場合(SH [X] .SUM> 0 ) SH [X] .LEN = C [SH [X] .R + 1 ] - C [SH [X] .L]; //完全覆盖 そう であれば(SH [X] .L == SH [X] .R) SH [X] .LEN = 0 ; //叶子结点 さもなければ SH [X] .LEN = SH [X + X] .LEN +のSH [X + X + 1 ] .LEN; //一般情况 } ボイドビルド(int型のx、int型 LL、INT RR) { SH [X] .L = LL。 SH [X] .R = RR。 SH [X] .SUM = 0 。 [X] .LEN SH = 0 ; 場合(LL == RR) のリターンを。 int型の半ば。 半ば =(LL + RR)>> 1 。 構築(X + X、LL、半ば)。 構築(X + X + 1、+ミッド1 、RR)。 } ボイド変化(int型のx、int型 LL、INT RR、INT V) { 場合(SH [X] .L> = 11 && SH [X] .R <= RR) { SH [X] .SUM + = V。 突き上げ(X)。 返します。 } int型ミッド。 半ば =(SH [X] .L + SH [X] .R)>> 1 。 もし(LL <= MID) 変化(X + X、LL、RR、V)。 もし(RR> MID) 変化(X + X + 1 、LL、RR、V)。 押し上げ(x); } int型のmain() { しながら(1 ) { TOT ++ 。 scanf関数(" %のD "、&N) もし(nは== 0 ) ブレーク。 用(int型 iは= 1 ; iが<= N iが++ ) のscanf(" %LF%LF%LF%LF "、&P [i]は.A、&P [i]は.B、&P [i]は.C&P [I] .D)。 K = 0 。 以下のための(int型 I = 1;私は++; iが<= N ) { Kを ++ 。 S [K] = P [i]は.A。 K ++ ; S [K] = P [i]の.C。 } ソート(S + 1、S + 1 + K)。 INT(S + M =ユニーク1 S +、1 - S- + K)1 。 用(int型 I = 1 ; I <= M iは++ ) ID [S [I] = I、C [I] =のS [i]は、 W = 0 。 にとって( W、CMP)。 int型i = 1 ; iは= <N; iは++ )//处理扫描线 { W ++ 。 [W] .L = ID [P [i]は.A]、[W] .R = ID [P [i]は.C]。 .num [W] = P [i]は.B; [W] .kind = 1 。 ワット ++ ; [W] .L = ID [P [i]は.A]、[W] .R = ID [P [i]は.C]。 .num [W] = P [i]の.D; [W] .kind = - 1 。 } ビルド(1、0、M + 1 )。 ソート(A + 1、A + 1 + ANS = 0 ; 以下のために(int型 I = 1 ; I <= W iは++ ) { 変化(1、[I] .L、[I] .r- 1は、[I] .kind)。 もし(I == w)の ブレーク。 ANS + =([I + 1 ] .num-[I] .num)* SH [ 1 ] .LEN; //统计答案 } のprintf(" テストケース#1%d個の\ n " 、TOT)。 printf(" 合計エリアを探検:%.2f \ n \ n " 、ANS)。 } }