正直に言うと、この質問は、最初に私は本当に互いに素セットであることを期待していませんでした。マークされたマークは、もはや答えに貢献していないことを意味した後にのみ、同じ時間を探しているので、最初の反応は、暴力をマーキングされるトピックを参照してください。しかし、これは明らかにそれにタイムアウトであるので、あなたはどのようなデータ構造を考えるために維持するために取ることができます。ではないが、出て来てほしいです。
私はバグが存在しない考えを話すことはありませんが、それもこの戦いを感じて、マークが維持されていない維持します。実装は非常に良いツリーラインの一部をマーキング、しかしときの情報の次の部分、情報の重複の前の範囲ならば、彼らはマークやトラブルのビットをヒットする必要があります正確にどのくらいのを見つけるために(それはこれら二つの両方のためにする必要がありますいくつかはマークをヒットされたかどうかを確認し、一緒に両方をマークし、その後、今回の寄与を差し引いしようとすると、間隔の長さのANSですが、一緒に両方のマークを得ることの長いセクションをカバーするためにどのように?単純に追加することができない、その場所が)良い位置決めありません
だから私のコードは次のような始まりました(非常に暴力的なしかし、考慮されていない点があります)
以下のために(int型 I = 1 ; I <= M; ++ I) { W [i]を.l1 = read()は、[I] .R1 = W )(読み取ります。 [I] .l2 W [i]は.R2 = W; =)(読み取る(読み出します)。 W [i]は.C = W [i]は.R1-W [i]は.l1 + 1 。 INT S1 = [I] .l1、S2 = W W [i]は.l2。 一方、(S1 <= W [i]は.R1 && S2 <= W [i]は.R2) { もし ANS ++(FLAGG [S1] && FLAGG [S2]!)。 FLAGG [S1] = 1、FLAGG [S2] = 1 。 S1 ++; S2 ++ ; } } のために(int型 I = 1 ++; iは= N < I)の 場合 ++ ANS(FLAGG [I]!)。
なぜこの戦いでも、それは間違っていると考えられていますか?
私は時間がかかるためにデータのセットを見つけました
8 3
6 6 2 2
3 3 7 7
6 7 3 4
答え出力は90,000ですが、正解は9000でなければなりません。
したがって、このアイデアは==バグを有することが見出されています
私たちは、情報のその後とき3枚目、6,2ブランドのマークを与え、ANS + 1、3,7ブランドマークを与えるために、ANS + 1、我々はに頼るません。単純にマーキングすることは、たとえば、データのこのセット、間違っていますマーク
1,5,8プラス3無印最後の5つのANS
しかし、マーキングは、の「数」とマークされなければなりません
最初のメッセージ
私たちは、6,2ブランドマーク1を与えます
記事の情報
私たちは、3,7ブランドのマーク2を与えます
記事の情報
私たちは、6,3が同じであることが判明し、その後1をマークし、マーク2が同じである、それは2,6,3,7,4が同じ数であると言うことです!そして、唯一の貢献ANS 1
だから、最終的ANS 4
抽象モデルは、その後、これを見て、==その互いに素設定ものではありません
思考が構築し、各点のセット、合併の対応点への各情報を確認することは簡単です。
しかし、時間はので、ここで非常に不思議なアルゴリズムが存在し、ばらばらのセットを倍増、n個のLOGNがオーバーに最適化することができ、渡すことができませんでした
#include <ビット/ STDC ++ H> に#define N 100003 の#define MOD十億七 の#defineは長い長いLL 使用 名前空間STDを、 INTはREAD() { int型のx = 0、F = 1。チャー S = GETCHAR()。 一方、(S < ' 0 ' || S> ' 9 '){ もし、(S == ' - ')、F = - 1 ; S = GETCHAR();} 一方、(S> = ' 0 ' && S <= ''){X = X * 10 + S- ' 0 ' ; S = GETCHAR();} 戻りのx *のF。 } INT F [N] [ 22 ]。 INT getfa(int型のx、int型のJ) { 場合(F [X] [J] == x)をリターンX。 リターン [X] [J] = F getfa(F [X] [j]は、j)は、 } ボイドマージ(int型のx、int型の Y、INT J) { F [getfa(X、J)] [J] = getfa(Y、J); } int型)(主 { INT、N =読み取る()、M = 読み取ります(); int型 ANS = 0、OP = 0 ; 以下のために(int型 i = 1 ; iは= N <; ++ I) のために(int型 J = 0 ; J <= 20 ; ++ j)は F [I] [J] = I。// 从iが2 ^ J的长度的区间、起始 ため(int型 i = 1 ; iが<= M; ++ I) { int型 L1 =読み取る()、R1 = 読み取ります(); INT L2 = read()は、R2 = 読み取ります(); 以下のための(int型 J =20である ; J> = 0 ; - J) IF(L1 +(1 << J) - 1 <= R1){マージ(L1、L2、J); L1 + =(1 << J); L2 + =(1 < <J)は;} // 再び開始、最大組み合わせ間隔を見つける移動 } ため(INT J = 20であり ; J> = 1。 ; - J) { ため(INT I = 1 ; I +(1 << J) - 。1 <= N-;私は++)// !!!その境界処理注 { マージ(I、getfa(I、J)、Jが - 1。); // その後、層を合わせ半部 マージ(私は+(1 <<(J- 1))、getfa(I、J)+(1 <<(J- 1))、J- 1 )。 } } int型 MD = 20 。 以下のために(int型 i = 1 ; iは= N <; ++ I) { 場合(getfa(I、0)== I)ANS ++ 。 } LL RES = 1 。 ANS - ; RESの =の解像度* 9%のMOD。 以下のために(int型私は= 1 ; I <= ANS; ++I) のRES =の解像度* 10%のMOD。 printf(" %LLDする\ n " 、RES)。 }