この問題に対する一つの解決後、またはそれを入れています。
A.Divisors
すべての数字のルートふるい需要要因は、再カウントに再びそれを掃引することができます。
#include <cstdioを> する#include <iostreamの> する#include <CStringの> する#include <ベクトル> の#include <地図> 使用して名前空間std。 const int型N = 205; ; [N]、M、N INT マップ<int型、int型> BU。 ベクトル<整数>解像度、アプリ。 INTのANS [N]。 INTメイン() { //freopen("dt.in","r",stdin)。 scanf関数( "%d個の%のD"、&N、&M)。 以下のために(INT I = 1; I <= M; iは++) { scanf関数( "%のD"、および[I])。 用(INTのJ = 1; 1LL * jは* jを<= [I]; J ++) { ([I]%のj)が続けば、 もし(jは* jを== [i])とres.push_back(J)。 他res.push_back(j)は、res.push_back([I] / J)。 } } int型SZ = RES。サイズ(); ための式(I 0 = int型、私はSZを<; Iは++します) { (RES [I]> n)を継続する場合、 IF(bu.find(RES [i])と== bu.end())app.push_back(RES [I])。 BU [RES [I]] ++; } SZ = app.size()。 以下のために(INT i = 0; iは<SZ、iは++) ANS [BU [アプリ[I]]] ++; ANS [0] = N-SZ。 以下のために(; I <= M I ++はI = 0 INT) のprintf( "%Dを\ n"、ANS [I])を 0を返します。 }
B.Market
オフラインで尋ねました。お問い合わせやお店は、年代順に、すべてが現行計画へのポインタがバックパックを実行するために入れて購入することができます維持しています。
彼は法案は、DP、単調の半分が最適解が可能見つけるように注意分接尾辞として非常に大きく、非常に小さな値、配列インデックスの、値であることを指摘しました。
#include <cstdioを> する#include <iostreamの> する#include <CStringの> する#include <アルゴリズム> 名前空間STDを使用して、 読み取りINT() { int型のx = 0、F = 1; CHAR CH = GETCHAR()。 (!isdigit(CH))、一方{IF(CH == ' - ')は、f = -1; CH = GETCHAR();} ながら(isdigit(CH))X = X * 10 + CH-'0' 、CH = GETCHAR()。 x * Fを返します。 } CONST INT INF = 0x3f3f3f3f。 [100005] F、M、N INT、ANS [100005]。 構造体ショップ { int型のC、V、T。 フレンドブール演算子<(店舗、ショップB) { <におけるリターンBT。 } } S [305]。 構造体のプラン { int型のT、NUM、ID。 友人のブール演算子<(プランB、計画) { <BTのリターン。 } } P [100005]。 ボイドショー() { ため(iは++; iは= N * 300 <I = 1 INT) << F [I] << ENDLをCOUTと、 } int型のmain() { /*freopen("dt.in","r",stdin)。 freopenは( "my.out"、 "W"、STDOUT); * / N =(読み取り); M =読み取ります()。 以下のために(INT i = 1; iが++; iが<= N) S)[I] .V(読み取りS =)S [i]は.C(リード= [I] .T読み取り=(); (; I <= M; I = 1 int型私は++)用 p)が(読み取る。= .T [I]、P [i]は.num = read()は、P [i]は.ID = I。 ソート(S + 1、S + N + 1);ソート(P + 1、P + M + 1)。 memsetの(F、0x3fを、はsizeof(F))。 F [0] = 0; int型J = 1; 以下のために(INT I = 1; I <= M; iは++) { 一方(j <= N && S [j]は.T <= P [I]。 F [K] =分([K]、F [KS [J] .V] + S [j]がF .C)。 (k--; kはint型のk = N * 300)のための [K] F =分([K + 1] F [k]はF)。 } // OW()。 // coutの<< P [i]は.ID <<」「<< P [i]を.num <<てendl; ANS [P [i]は.ID] = UPPER_BOUND(F + 1、F + N * 300 + 1、P [i]は.num)-F-1。 } (i = 1 int型; I <= M; iが++)のため のprintf( "%d個の\ n"、ANS [I])。 0を返します。 }
C.Dashスピード
その後側からの視点の変化は、実現可能な速度から開始し、実行する現在のコレクションの側に追加していくように思えませ検討し、直径が究極の辺集合への答えです。
次のセグメントツリー標準のレートを確立し、間隔制限挿入側(同様の衛星へ、又は直接前行ベクトル方法)に準拠します。
$ O(nは\ログ\ n)が1回のセグメントツリー除算の$とすべての答えを征服することにより、そのことができます後。セグメントツリー到着間隔は、接続されたエッジと、本明細書の点の集合が存在することになります。具体的な合併は、新しい中国聯通ブロックの終点を決定するために、状況の6種類を議論するために、前にその質問のようなものです。
構造は互いに素設定不可逆途中変更できないようにパーティションは、影響を逆にする必要がバックトラック、バックトラックを必要とするので、すなわち、パスが圧縮できません。そこでここでは、マージする別の方法を必要とする - ランクでマージします。
スタックによって記録された変更に関する情報の後に、あなたが引き出すことができたときに戻って飛び出ます。
#include <cstdioを> する#include <iostreamの> する#include <CStringの> する#include <ベクトル> の#include <cmath> の#define再登録 名前空間stdを使用。 名前空間IO { の#define BUF_SIZE 100000 の#define OUT_SIZE 100000 の#defineが長い長いっ // fread->読み取る BOOLのioerror = 0。 インラインチャーNC(){ [BUF_SIZE] BUF静的CHAR、* P1 = BUF + BUF_SIZE、* PEND = BUF + BUF_SIZE。 IF(P1 == PEND){ P1 = BUF。PEND = BUF +のfread(BUF、1、BUF_SIZE、STDIN)。 (PEND == P1)場合{のioerror = 1、-1を返す;} // {のprintf( "IOエラーを\ N!");システム( "一時停止");(;;)のために、出口(0); } インラインブールブランク(チャーCH){戻りCH == ' '|| CH ==' \ n '|| CH ==' \ R '|| CH ==' \ Tを';} インラインボイドリード(INT&X ){ BOOL符号= 0。チャーCH = NC()。X = 0。 用(;ブランク(CH)、CH = NC())。 (例外IOError)の復帰であれば、 IF(CH == ' - ')記号= 1、CH = NC()。 用(; CH> = '0' && CH <= '9'; CH = NC())X = X * 10 + CH-'0' 。 (記号)は、x = -xであれば、 } インラインボイド読み取る(LL&X){ BOOL符号= 0。チャーCH = NC()。X = 0。 用(;ブランク(CH)、CH = NC())。 (例外IOError)の復帰であれば、 IF(CH == ' - ')記号= 1、CH = NC()。 用(; CH> = '0' && CH <= '9'; CH = NC())X = X * 10 + CH-」0' ; (記号)は、x = -xであれば、 } インラインボイドリード(ダブル&X){ BOOL符号= 0。チャーCH = NC()。X = 0。 用(;ブランク(CH)、CH = NC())。 (例外IOError)の復帰であれば、 IF(CH == ' - ')記号= 1、CH = NC()。 用(; CH> = '0' && CH <= '9'; CH = NC())X = X * 10 + CH-'0' 。 (CH == '')であれば{ ダブルTMP = 1。CH = NC()。 用(; CH> = '0' && CH <= '9'; CH = NC())TMP / = 10.0、X + = TMP *(CH-'0' )。 } (記号)は、x = -xであれば、 } インラインボイド(チャー*秒){読み取り チャーCH = NC()。 用(;ブランク(CH)、CH = NC())。 (例外IOError)の復帰であれば、 (!;空白(CH)&&例外IOError;!CH = NC())* S ++ = CHため、 * S = 0。 } (例外IOError){C = -1;返す;}もし } // fwrite->書き込み 構造体Ostream_fwrite { チャー* BUF、* P1、* PEND。 Ostream_fwrite(){BUF =新しいCHAR [BUF_SIZE]; P1 = BUF;保留= BUF + BUF_SIZE;} アウトボイド(チャーCH){ IF(P1 == PEND){ 関数fwrite(BUF、1、BUF_SIZE、STDOUT); P1 = BUF。 } * P1 ++ = CH。 } ボイドプリント(INT X){ 静的チャーS [15]、*、S1、S1 = S。 (!x)は、* S1 ++ = '0'の場合、(x <0の)アウト( ' - ')の場合、X = -x; 一方、(X)* S1 ++ = X%10 + '0'、X / = 10。 しばらく(S1 - = S!)アウト(* S1)。 } ボイドのprintln(INT X){ 静的チャーS [15]、*、S1、S1 = S。 しばらく(S1 - = S!)アウト(* S1)。アウト( '\ n')で。 (!x)は、* S1 ++ = '0'の場合、(x <0の)アウト( ' - ')の場合、X = -x; 一方、(X)* S1 ++ = X%10 + '0'、X / = 10。 しばらく(S1 - = S!)アウト(* S1)。アウト( '\ n')で。 } ボイドプリント(LLのX){ 静的チャーS [25]、*、S1、S1 = S。 (!x)は、* S1 ++ = '0'の場合、(x <0の)アウト( ' - ')の場合、X = -x; 一方、(X)* S1 ++ = X%10 + '0'、X / = 10。 しばらく(S1 - = S!)アウト(* S1)。 } ボイドのprintln(LLのX){ 静的チャーS [25]、*、S1、S1 = S。 (!x)は、* S1 ++ = '0'の場合、(x <0の)アウト( ' - ')の場合、X = -x; 一方、(X)* S1 ++ = X%10 + '0'、X / = 10。 } ボイドプリント(二重のx、int型のY){ MUL [] = {1,10,100,1000,10000,100000,1000000,10000000,100000000、LL静的 1000000000,10000000000LL、100000000000LL、1000000000000LL、10000000000000LL、 100000000000000LL、1000000000000000LL、10000000000000000LL、100000000000000000LL}。 IF(X <-1E-12)アウト( ' - ')、X = -x; X * = MUL [Y]。 LL×1 =(LL)床(X)(X-床(X)> = 0.5)++ X1場合。 LLのX2 = X1 / MUL [Y]、X3 = X1-X2 * MUL [Y]。印刷(×2)。 もし(Y> 0){OUT( ''); (i = 1からsize_tのうち( '0')、++ I; iがMUL [I] <MUL [Y] * Y && X3を<)のために、プリント(X3);} } ボイドのprintln(ダブルのx、int型のY){プリント(x、y)は、OUT( 'の\ n');} ボイドプリント(チャー*秒){(* S ++(* S)うち一方);} ボイドのprintln(チャー*秒){ながら(* S)OUT(* S ++);アウト( 'の\ n');} ボイドフラッシュ(){IF(!P1 = BUF){関数fwrite(BUF、1、P1-BUF 、STDOUT); P1 = BUF;}} 〜Ostream_fwrite(){ フラッシュ();} }のostream。 インラインボイドプリント(INT X){Ostream.print(x);} インラインボイドのprintln(INT X){Ostream.println(x);} インラインボイドプリント(チャーX){Ostream.out(x);} インラインボイドprintln(チャーX){Ostream.out(X); Ostream.out( 'の\ n');} インラインボイドプリント(LLのX){Ostream.print(x);} インラインボイドのprintln(LLのX){のostream。 println(x);} インラインボイドプリント(二重のx、int型のY){Ostream.print(X、Y);} インラインボイドのprintln(ダブルのx、int型のY){Ostream.println(X、Y);} インラインボイドプリント(CHAR *秒){Ostream.print(S);} インラインボイドのprintln(チャー*秒){Ostream.println(S);} インラインボイドのprintln(){Ostream.out( 'の\ n');} インラインボイドフラッシュ(){Ostream.flush( );} #undefのLL の#undef OUT_SIZE の#undef BUF_SIZE }。 CONST int型N = 1E5 + 5。 N INT、M。 [N << 4]、ヘッド[N << 4]、NXT [N << 4]、TOT、FR [N << 4]〜INT。 int型FA [N]、サイズ[N]、息子[N]、上位[N]、DEP [N]、ANS [N]; ベクター<INT> G [N]。 #define LS(K)(K)<< 1個 の#define RS(K)(K)<< 1 | 1つの 構造体スタック { int型のX、Y、OP、ND1、ND2。 } S [N << 4]。 トップのint; ボイドイン(int型K、int型のL、int型のR、int型のL、int型のR、int型のx、int型のY) { IF(L <= 1 && R> = R) { FR【TOT] = xと; ++ TOT = Yであり; NXT [TOT =頭部[K];頭部[K] = TOT。 返します。 } INT半ば= L + R >> 1。 IF(L <= MID)イン(LS(k)は、L、中、L、R、X、Y)。 IF(R> MID)イン(RS(K)、中間+ 1、R、L、R、X、Y)。 { サイズは、[X] = 1; FA [x]はFを=。 INT SZ = G [X] .size()。 以下のために(; iはSZを<; I = 0 int型私は++) { int型、Y = G [X] [I]; (Yの== fは)継続する場合。 DEP [Y] = DEP [X] +1。 DFS1(Y、X)。 サイズ[X] + =サイズ[Y]。 (サイズ[Y]>サイズ[息子[X]])息子が[X] = yの場合。 } を返します。 } ボイドDFS2(int型のx、int型F) { TOP [X] Fを=。 (!息子[X])であればリターン。 DFS2(息子[X]、F)。 INT SZ = G [X] .size()。 以下のために(; iはSZを<; I = 0 int型私は++) { int型、Y = G [X] [I]; (もし!トップ[Y])DFS2(Y、Y); } } int型LCA(int型のx、int型Y) { (TOP [X]!= TOP [Y])一方 { IF(DEP [TOP [X] <DEP [トップ[Y])スワップ(x、y)は; X = FA [TOP [X]]。 // COUT << X <<」「<< Y << ENDL。 } 戻りDEP [X] <DEP [Y]は、x:yの。 } INT DIS(int型のx、int型Y) { DEPを返す[X] + DEP [Y] - (DEP [LCA(X、Y)] << 1)。 } 名前空間U { INT FA [N]、ノード[N] [3]、RK [N]。 ボイドINI() { ため(; iがn = <; I = 1 int型私は++) FA [I] =ノード[i]が[0] =ノード[I] [1] = I。 } INT findf(INT X) { FAを返す[X] == X X:findf(FA [X])。 } ボイドマージ(INT XX、YY INT、INT&D) { INT X = findf(XX)、Y = findf(YY)、ND1、ND2、MAXD = -1、nowd = DIS(ノード[X] [0]、ノード[X] [1])。 IF(nowd> MAXD)MAXD = nowd、ND1 =ノード[X] [0]、ND2 =ノード[X] [1]。 nowd = DIS(ノード[Y] [0]、ノード[Y] [1])。 IF(nowd> MAXD)MAXD = nowd、ND1 =ノード[Y] [0]、ND2 =ノード[Y] [1]。 ため(RE値int i = 0; iは<2; I ++) のための(再INT J = 0であり、j <2、J ++) { nowd = DIS(ノード[X] [i]と、ノード[Y] [J])。 IF(nowd> MAXD)MAXD = nowd、ND1 =ノード[X] [i]は、ND2 =ノード[Y] [J]。 FA [Y] = xで、ノード[X] [0] = ND1、ノード[X] [1] = ND2。 } } D = MAX(D、MAXD)。 IF(RK [X] <RK [Y])スワップ(X、Y) S [++トップ] =(スタック){X、Y、0、ノード[X] [0]、ノード[X] [1]}。 IF(RK [X] == RK [Y])++ RK [X]、S [トップ] .OP = 1。 } ボイドキャンセル(int型K) { 一方(TOP> K) { U :: RK [S [トップ] .X] - = S [トップ] .OP。 U :: FA [S [トップ] .Y] = S [トップ] .Y。 U ::ノード[S [トップ] .X] [0] = sの[トップ] .nd1。 U ::ノード[S [トップ] .X] [1] = sで[トップ] .nd2。 上 - ; } } ボイドワーク(int型K、int型のL、int型のR、int型の合計) { int型のPOS =トップ。 (I =ヘッド[K] INT再; I;私は= NXT [i])とするための U ::([i]は、合計に対するFR [I]を、)マージ。 IF(L == R) { ANS [L] =合計。 (POS)をキャンセル。 返します。 } INT半ば= L + R >> 1。 ワーク(LS(k)は、L、中、和)。 ワーク(RS(K)、中間+ 1、R、合計)。 COUT << I << ' '<<サイズ[I]を<<'' << (POS)をキャンセル。 } INTメイン() { //freopen("speed2.in","r",stdin)。 IO(n)を読み出す::; IOは(m)を読み出す::。 ため(再int型i = 1; iがn <; iは++) { int型、X、Y、L、R。 IO(x)は読み取り::、IO(Y)の読み取り::。 IOは、(L)読み取り::; IOは(R)読み出し::。 G [X] .push_back(Y)。 G [Y] .push_back(X)。 イン(1,1、N、L、R、X、Y)。 } DEP [1] = 1。 DFS1(1,0); DFS2(1,1)。 / *のための(I = 1をint型、iが<= N; I ++) U :: INI(); ワーク(1,1、nは、0)。 (M--)一方 { INT Q。 IOは、(q)を読んで::; IO ::のprintln(ANS [Q])。 } 0を返します。 }