問題のSCOI2016孟孟ダ・ソリューション
考え
このトピックでは、おそらく間隔が等しくなるように、そして非常に巧妙なアイデアは、インセット互いに素で2つの店舗に間隔を制限することで、あなたにいくつかの制限を与えます
私たちは、互いに素セットの数の一つだけ聞いて、答えは(トン我々が求めるすべてが唯一の番号で、セットを確認してください)
しかし、大規模な複合体を介し直接操作
それから誰か倍増を考えます
f[i][j]
[間隔を表し 、 ここで、互いに素なセット]
彼の息子について非常に最初の主要な各セクションを記録
入力 l1
l2
r1
r2
STテーブルと同じ時間をマージ
場合は再プロセスの各大型間隔、f[i][j]
およびf[a][b]
彼らの息子が互いに素セットについても、ばらばらのセットでは、我々は、マージ(左息子と左マージ情報の息子の大規模な範囲の周囲を通過することができるようになります息子の合併、右の統合と、右の息子の息子)
最終タリーf[i][0]
互いに素セットに数の
書式#include <iostreamの> の#include <cstdioを> する#include <cmath> の#include <CStringの> の#include <アルゴリズム> に#define再登録int型 の#define LL長い長い の#define MN 1000050 の#defineのmod 1000000007 使って 名前空間はstd; INT BCJ [MN * 22 ]、F [MN] [ 22 ]、LC [MN * 22 ]、RC [MN * 22 ]、LG [MN]。 INTのN、M、K、LTK、CNT。 INT(見つけるINT X){ 場合(X == BCJ [X])戻りXと、 BCJ [X]= (BCJ [X])を見つけます。 戻りBCJ [X]。 } ボイドマージ(int型のx、int型のY){ int型の T1 =(X)、T2 =見つける検索(Y)。 もし(!T1 = T2)BCJ [T2] = T1。 } int型のmain(){ scanf関数(" %D%dの"、&N、&M)。 ため(再I = 2 ; iが= <N; iは++ ) LGを[I] = LG [I / 2 ] + 1 。 用(RE J = LG [n]は、J> = 0 ; j-- ) のための(iは=再1、I +(1 << J) - 1 <= N; I ++ ){ F [I] [J] = ++ CNT; BCJ [CNT] = ; CNT } // 数値の大きい範囲に するため(J =再。1 ; J <= LG [N-]; J ++ ) のための(RE I = 1 ; Iは、(+ 1 << J) - 1 <= N; I ++は){ LC [F [I] [J] = F [I]、[J- 1 ] ; RC [F [I] [J] = F [Iは、+(1 <<(J- 1))] [J- 1 ]; } // 息子に関する統計 のために I(=リ1 ; I <= M; iは++ ){ int型A1、A2、A3、A4。 scanf関数(" %D%D%D%D "&A1&A2&A3&A4)。 int型 L = LG [A2-A1 + 1 ]。 マージ(F [A1] [L]、F [A3] [L])。 マージ(F [A2 - (1 << L)+ 1 ] [L]、F [A4-(1 << L)+ 1 ] [L])。 } // 像ST表一样合并 ため(I =再1 ; iは= CNT <; iは++ ){ 場合(!の!LC [I]を|| RC [i])と続けます。 int型の T1 = (I)を見つけます。 もし(!T1は= I)が{ マージ(LC [T1]、LC [I]); マージ(RC [T1]、RC [I]); // [I] [J]およびF [A] [B Fもし】リンクブロックに属し、これらは左右の息子ユニコムブロックに属する } } LTK = N-; // 各ブロックの位置を想定している独立ユニコム、ユニコムあればマイナス のための(I =再1。 ; I <= N- ; Iは++ ){ IF(検索(F [I] [ 0 [!])= F [I] 0 ]) LTK - ; } LL ANS = 9 ; のため(RE I = 1は、私がLTK <; I ++ ) ANSを =(ANS%MOD * 10)%モッズ; printf(" %のLLD "、ANS%のMOD)。 リターン 0 ; }