問題B:集合論S U B S E T
制限時間:1秒 メモリ制限:512メガバイト
フェイス質問
彼は公に質問に直面して減少しました。
問題の解決策
直接配列によってシミュレートしているようです。
しかし、私はビットセット&操作が問題の交差点に最適なソリューション、完全にビットセットの期間の中央値の複雑さの影響を無視することができると感じました。
塩基:インサートの各要素について、(負の値を有する)第一塩基を添加し、次いでビットセットに挿入しました。
そして設定:各要素に挿入直接決定力が現在のビット集合内に存在するかどうかについては、そこに答えに全く蓄積されず、そして存在するように設定。
交差点:まずゼロに答えると、新しいビットセットを作成します。挿入された各要素について、暴力は依然として強い文はビットセットに存在するか、捨て存在しない場合、その後、答えに累積があります。
1.スクロール:この新しいビットセット、およびオリジナルの合併のためにビットセットは3つの方法があります。(最良の選択)2割り当て。(T85)3.激しく相。(おめでとうTフライ)。
同時に、プラス1:2つのオプション:1.bitset全体的な権利。2.base--(おめでとうT飛びます)。(優れたアルゴリズム)
上記とは対照的に低減します。
だから、ビットセットビット演算、およびについて少し。2E6は、この場合には、まだ非常に遅いです。
コード:
#include <ビット/ STDC ++ H> ((A)A = INITを読み取るの#define)は RINTがint登録#defineする 名前空間stdを使用。 チャーXCH、xBの[1 << 15]、* XS(xBの)、* XTT式(XB) #define GETC()(XS == XTT &&(XTT =(XS =のxB)+関数fread(xBで、1,1 << 15、STDIN)、XS == XTT)0:* XS ++) インラインINTのinit() { INT X = 0、F = 1; CHAR CH = GETC()。 一方、(CH < '0' || CH> '9'){IF(CH == ' - ')は、f = -1; CH = GETC();} 一方(CH> = '0' && CH <= '9 '){X =(x << 3)+(X << 1)+ CH-'0'; CH = GETC();} 戻りのx * Fを、 } int型M、SIZ、ウェイ、選ぶ、和、AI、余分。 長い長いANS; ビット集合<2000004>ビット[2]。 メイン() { 読み取り(M);ウェイが= 1000000;余分= 1000000。 今= 1 int型。 IF(OPT == 1) { リード(合計)。 (sum--)しながら { (AI)を読み取ります。 IF(!ビット[今] [AI +ウェイ]) { ANS + = AI、++ SIZ。 ビット[今] [AI +ウェイ] = 1。 } } のprintf( "%LLDを\ n"、ANS)。 } そうであれば(OPT == 2) { ANS = SIZ = 0。 (合計)を読み取ります。 (sum--)しながら { (AI)を読み取ります。 IF(ビット[今] [AI +ウェイ]) { ビット[今^ 1] .SET(余分+ AI)。 ANS + = AI、++ SIZ。 } } ウェイ=余分。 ビット[今] .RESET()。 今^ = 1; printf( "%LLDする\ n"、ANS)。 } - {; ANS + = SIZ;のprintf( "%LLDする\ n"、ANS)ウェイ}そうでなければ(OPTの== 3)場合 のprintf( "%のLLDを\ n"、;そうでなければ{++ウェイ; ans- = SIZ ANS);} } 0を返します。 }