質問の意味:
そしてmは無向エッジを与えられて、各エッジは、このエッジによって、この範囲内の人々のボリュームという意味$ [L、R] $、ボリュームから1を作るために持っているどのように多くの依頼する可能性がありますnは1〜
アイデア:無向エッジ、1及びnの接続であるように互いに素なセットを用いて維持することができます。
最も暴力的なアプローチ、各列挙子ボリュームを考えるボリュームが互いに素なセットと現在のエッジに維持することができ、それは、nの接続を1に決定されます。
その後、この子を残して、接続性を決定、離散でなければならないすべてのセクションの最初の最適化を考えてみましょう、と私たちは、その後も、ばらばらセットと各サブセクションの側を見て、どのような方法を分割ツリーラインに従い、個別の間隔をすることができとき間隔、それにさえばらばらセットエッジ・オペレーティング・リターン。
各エッジは、すなわち、ログ間隔に分割されているので、オープン時間を記録、互いに素なセットタイムログを追加され、時間複雑度は、(N * LOGNの*のLOGN)、ログは互いに素セットもたらされる、請求、定数は小さいです。
時間の互いに素セット合併を完了すると、ランク、およびバック動作のみ連続期間によって取消、2 * N番目の点の離散化があり、セグメントツリーポイントは、あまりにも開いてはいけません。
#include <ビット/ STDC ++ H> の#define(iは= int型、iが= Bを<; I ++の)のための担当者(I、B) の#define DEP(I、B、A)(iはBを= int型のため、 I> =; i--) の#define PB(x)の一back(X) の#define PII対<整数、整数> 使用して 名前空間STDを、 const int型 MAXN = 200010 ; ベクター < INT > TR [MAXN << 2 ]。 INTのN、M。 構造体の縁{ int型、U、V、L、R。 } [MAXN]。 INT B [MAXN << 1 ]、CNT、ANS。 int型FA [MAXN]、SIZ [MAXN]。 int型を見つける(int型X){ 戻り [x]はx == FAか?X:(FAが[X])を見つけます。 } ボイド更新(int型、O INTの L、INT R、INT QL、INT QR、INT I){ 場合(QL <= L && R <= QR){ TR [O] .pb(I)。 返します。 } INT半ば=(L + R)>> 1 。 もし(QL <= MID)更新(O << 1 、L、中間、QL、QR、I)。 もし(MID <QR)更新(O << 1 | 1、中間+ 1 、R、QL、QR、I)。 } 無効 DFS(INT O、int型の L、int型R){ ベクトル <PII> まし。 INT SI = TR [O] .size()。 担当者(I、0、SI- 1 ){ int型のid =のTR [O] [I]。 INT U = A [ID] .U、V = [ID] .V。 int型 FU =(U)を見つけ、FV = のfind(V); もし(フー== FV)は継続。 もし(SIZの[フー]> SIZ [FV])スワップ(FU、FV)。 FA [FU] = FV。 int型の D = 0 ; もし(SIZの[フー] == SIZ [FV])D ++; SIZ [FV] + = D。 ve.push_back({FU、D})。 } INT半ば=(L + R)>> 1 。 もし(見つける(1)== )N(見つける){ ANS + = B [R + 1 ] - B [L]。 } そう であれば(L < R){ DFS(O << 1 、L、MID)。 DFS(O << 1 | 1、ミッド+ 1 、R); } SI = ve.size()。 DEP(I、SI - 1、0){ SIZ [FAは[i]が1次回] [まし] = - ; .second [I]まし FA [i]は1次回[まし] = 1次回[i]はまし。 } } int型のmain(){ CIN >> N >> M。 担当者(I、1 、N){ FA [I] = I。 SIZ [I] = 1 。 } のための(int型 I = 1 ; I <= M; iが++ ){ scanf関数(" %D%D%D%D "、および[I] .U、&[I] .V、&[I] .L、 &[I] .R)。 B [ ++ CNTは] = [I] .L。 B [ ++ CNTは] = [I] + .R1 ; } ソート(B + 1、B + 1本の + CNT)。 CNT =一意(B + 1、B + 1 + CNT)-B- 1 。 以下のために(int型 I = 1 ; I <= M; iは++ ){ [I] .L = LOWER_BOUND(B + 1、B + 1本の + CNT、[I] .L) - B。 [I] .R = LOWER_BOUND(B + 1、B + 1本の + CNT、[I] .R + 1) - B。 アップデート(1、1、CNT、[I] .L、[I] .r- 1 、I)。 } DFS(1、1 、CNT)。 printf(" %d個の\ n " 、ANS)。 }