グランドコンテストAtCoder 038簡単な説明

ここからスタート

01マトリックスの問題

 コード

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
ブールブールのtypedef。

CONST int型N = 1E3 + 5。

INT W、H、A、B。

INTメイン(){ 
	scanf関数( "%D%D%D%D"、&W、およびH&A、&B); 
	以下のために(INT i = 0; iはWを<; iは++){ 
		(int型J = 0であり、j <H、J ++)のための{ 
			のputchar( '0' ^(iはBを<)^(J <A))。
		} 
		のputchar( 'の\ n'); 
	} 
	0を返します。
}

セグメントの並べ替え問題のB

  得られたを注文せずに選択された2つの断面の同じシーケンス場合。だから、何もしなかった二回の並べ替えに等しいです。

  あなたが支払う必要がある場合、2つのセクションが$ [L_1、R_1] $と$ [L_2、R_2] $、$(L_1 <L_2)$であると仮定する。そして、$ [L_1、L_2)$は、最低$でなければなりません(L_2 - 昇順でL_1)$番号、$(R_1、R_2] - 昇順で$番号R_1 $は最大$(R_2でなければなりません)。

コード

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
ブールブールのtypedef。

CONST int型N = 2E5 + 5。

INT、N、K。
INT [N]、Q [N]。
ブールismx [N]、ISMI [N]。

INTメイン(){ 
	scanf関数( "%d個の%のD"、&N、&K)。
	以下のために{(INT i = 1; iが++; iが<= N)
		(+ I、 "%のD")のscanf。
	} 
	ST = 1、ED = 0 int型。
	以下のために(INT I = N; I; i--){ 
		(ST <= ED && Q [ST]は> = iがK + 1)一方
			ST ++。
		(ST <= ED && [Q [編]]> [I])一方
			ed--。
		Q [++編] = I; 
		ISMI [I] =(ST == ED)。
	} 
	ST = 1、ED = 0。
	以下のために(INT i = 1; iは= N <; iは++){ 
		ながら(ST <= ED && Q [ST] <
		(ST <= ED && [Q [編] <[I])一方
			ed--。
		Q [++編] = I; 
		ismx [I] =(ST == ED)。
	} 
	INT QAQ = 0。
	{(; iは<= n iはjは= I = 1、J = 1 INT)ため
		++ J。
		一方、([J]> [J - 1])
			J ++。
		QAQ + =(J - I> = K)。
	} 
	INT ANS = N - K + 1 -マックス(QAQ - 1、0); 
	{(私は++; iが<= N int型I = K + 1)のため
		= ISMI [I - - K] && ismx [I] ANS。
	} 
	のprintf( "%d個の\ n"、ANS)。
	0を返します。
}

問題のC LCMS

  基本的な抗ドリル演習。

コード

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
ブールブールのtypedef。

#defineは長い長いっ

空隙exgcd(int型B INT、INT&X、INT&Y){ 
	(!b)は、{もし
		、X = 1、Y = 0 
	}他{ 
		exgcd(B、%のB、Y、X)。
		Y - =(A / B)* X。
	} 
} 

int型INV(int型N、INT){ 
	int型のX、Y。
	exgcd(N、x、y)は、
	リターン(x <0の)?(X + N):(X)。
} 

CONST INTモッド= 998244353。

テンプレート<constのint型のMod = ::モッズ> 
クラスZ { 
	パブリック:
		int型のV; 

		Z():V(0){} 
		Z(int型X):V(X){} 
		Z(LLのX):V(X%MOD){} 

		Z演算子+(Z b)は{
			int型のX;
			Z(((X = V + BV)> = MOD)(X - MOD):(X))を返します。
		} 
		Z演算子- (Z b)は{ 
			int型のX; 
			Z(((X = Vを- BV)<0)、(X + MOD)?:(x))を返します。
		} 
		Z演算子*(Z b)は{ 
			戻りZ(V * 1LL * BV)。
		} 
		Z演算子〜(){ 
			戻りINV(V、MOD)。
		} 
		Z演算子( - ){ 
			戻りZ(0) - *この; 
		} 
		Z&演算子+ =(Z b)は{ 
			返す*この= *この+ B。
		} 
		Z&演算子- =(Z b)は、{ 
			と、b - *この= *これを返します 
		} 
		Z&演算子* =(Z b)は{ 
			*この= *本* bを返します。
		} 
}。

Z <> qpow(Z <> A、int型P){
	Z <> RT = Z <>(1)、PA =。
	(P >> = 1、PA = PAの*のPA; P){ため
		(P&1){もし
			RT = RT * PA。
		} 
	} 
	戻りRT; 
} 

Z <>紫のtypedef。


CONST int型N = 2E5 + 5。
const int型のV = 1E6 + 5。

int型のn; 
ZI F [V]。
ZI Invの[V]。

INTのmain(){ 
	int型のM = 0。
	scanf関数( "%のD"、&N); 
	ZI ANS = 0。
	{ため(iは++; iは= <N I = 1であり、X INT)
		のscanf( "%d個"、&x)は、
		F [X] + = X。
		ANS - = xと; 
		M = MAX(M、X)。
	} 
	ため(INT I = 1; I <= M; iは++){ 
		ため(int型J =私+; jは<= M; J + = 1){ 
			F [I] + = F [J]。
		}  
	}
	ため(INT I = 1; I <= M。
	} 
	ための式(I = mをint型、iが; i--){ 
		ため(int型J = iは+ I; J <= M; J + = 1){ 
			F [1] - = F [J]。
		} 
	} 
	INVは、[1] 1 =。
	以下のために(INT I = 2; I <= M; iは++){ 
		Invの[I] =(-inv [モッドの%I] *(MOD / I))。
	} 
	ため(INT I = 1; I <= M; iは++){ 
		IF(F [i]が.V){ 
			ANS = ANS + F [I] * Invの[I]。
		} 
	} 
	ANS = ANS *((MOD + 1)>> 1)。
	printf( "%d個の\ n"、ans.v)。
	0を返します。
}

問題D一意のパス

  最初の関係は、リングパスと等価ではありません。

  最初の関係は明らかに推移し、対称性は互いに素セットメンテナンスを使用することができます。

  第二点は、第一の関係、次いでない溶液と通信して同じブロックを満たす場合。

  第二の通信関係の数がレイド決意ブロックを必要とする場合ポイントを取り、各通信ブロックは、2に等しいです。

  木や木のリングに接続されたエッジの最小数です。

  通信ポイントアウトブロック当たりのエッジの数まで、さらには完全に図ことができます。

コード

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
ブールブールのtypedef。

CONST int型N = 1E5 + 5。

#define PII対<整数、整数> 
の#defineっ長い長い

int型N、Q。
LLのM; 
INT UF [N]。
ベクトル<PII> E0、E1; 

INT(INT X){見つける
	UF [X] == Xを返しますか?X:UF [X] =(UFは、[X])を見つけます。
} 
ブールユニット(INT X、int型のY){ 
	X =(X)を見つける、Y =(y)を見つけます。
	(x ^ y)の場合{ 
		UF [X] Yを=。
		trueを返します。
	} 
	falseを返します。
} 

ボイドquitf(ブール式){ 
	IF(式){ 
		プット( "いいえ")。
		出口(0); 
	} 
} 
 
{main()のint型
	のscanf( "%D%LLD%D"、&N、&M&Q)。
	以下のために(INT i = 1; iが<= N; iは++)
		UF [I] = I。
	{(; I <= Q iが++ i = 1、U、V、オプトINT)のため
		のscanf( "%D%D%D"、&U&V、&OPT)。
		++ U、V ++; 
		IF(OPT == 0){ 
			E0.emplace_back(U、V)。
		}他{ 
			E1.emplace_back(V、U)。
		} 
	} 
	のための(自動E:E0)
		ユニット(e.first、e.second)。
	(自動E:E1)のため
		quitf(見つける(e.first)==のfind(e.second)); 
	int型のCOMP = 0; 
	以下のために(INT i = 1; iは= N <; iは++)
		COMP + =見つける(I)== I。
	quitf(E1.size()&& COMP == 2)。
	LL MI =((E1.size())(N):(N - 1))。
	quitf(M <MI || M> MX)。
	プット(「はい」)。
	0を返します。
}

問題のEガチャポン

  最小 - 最大および除外は、その後、DPに、最小要件は$ K $倍の確率に希望の時間を埋めるために充填するフルませんでし考えます。

コード

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
ブールブールのtypedef。

#defineは長い長いっ

空隙exgcd(int型B INT、INT&X、INT&Y){ 
	(!b)は、{もし
		、X = 1、Y = 0 
	}他{ 
		exgcd(B、%のB、Y、X)。
		Y - =(A / B)* X。
	} 
} 

int型INV(int型N、INT){ 
	int型のX、Y。
	exgcd(N、x、y)は、
	リターン(x <0の)?(X + N):(X)。
} 

CONST INTモッド= 998244353。

テンプレート<constのint型のMod = ::モッズ> 
クラスZ { 
	パブリック:
		int型のV; 

		Z():V(0){} 
		Z(int型X):V(X){} 
		Z(LLのX):V(X%MOD){} 

		Z演算子+(Z b)は{ 
			int型のX;
			Z(((X = V + BV)> = MOD)(X - MOD):(X))を返します。
		} 
		Z演算子- (Z b)は{ 
			int型のX; 
			Z(((X = Vを- BV)<0)、(X + MOD)?:(x))を返します。
		} 
		Z演算子*(Z b)は{ 
			戻りZ(V * 1LL * BV)。
		} 
		Z演算子〜(){ 
			戻りINV(V、MOD)。
		} 
		Z演算子( - ){ 
			戻りZ(0) - *この; 
		} 
		Z&演算子+ =(Z b)は{ 
			返す*この= *この+ B。
		} 
		Z&演算子- =(Z b)は、{ 
			と、b - *この= *これを返します 
		} 
		Z&演算子* =(Z b)は{ 
			*この= *本* bを返します。
		} 
}。

Z <> qpow(Z <> A、int型P){
	Z <> RT = Z <>(1)、PA =。
	(P >> = 1、PA = PAの*のPA; P){ため
		(P&1){もし
			RT = RT * PA。
		} 
	} 
	戻りRT; 
} 

Z <>紫のtypedef。

CONST int型N = 405。

int型のn; 
INT A [N]、B [N]。
ZI F [2] [N] [N]。
ziは[N]、[N]をとかします。

INTメイン(){ 
	scanf関数( "%のD"、&N); 
	int型須磨= 0、SUMB = 0; 
	以下のために{(INT i = 1; iが++; iが<= N)
		(A + I B + I、 "%d個の%のD")のscanf。
		スマ+ = A [i]は、
		SUMB + = B [i]は、
	} 
	[0] [0] = 1くし。
	(; I <= SUMB; iは1 = int型私は++)のために{ 
		[I] [0] = [I] = 1 [i]の櫛くし。
		(INT J = 1、J <I、J ++)のために{
			櫛[I] [J] =櫛[I - 1] [J - 1] +櫛[I - 1]〜[J]。
		} 
	} 
	int型CUR = 0。
	スマ= SUMB = 0。
	F [CUR] [0] [0] = 1; 
	以下のために(INT i = 1; iが<= N; iは++){ 
		memsetの(F [CUR ^ = 1]、0、はsizeof(F [0])); 
		{(SA ++; SA <=スマINT SA = 0)のための
			ための(INT SB = 0; SB <= SUMB; SB ++){ 
				紫V = F [CUR ^ 1] [SA] [SB]。
				もし継続(VV!)。
				ZI PW = 1。
				F [CUR] [SA] [SB] + = V。
				(INT J = 0; J <B [i]は、jは++、PW * = A [i])とするための{ 
					F [CUR] [SA + A [I] [SB + J] - = SB + j]をくし[J] * PW * V。
				} 
			} 
		} 
		スマ+ = A [i]は、
		SUMB + = B [i]は、
	} 
	紫ANS = 0。
	{(; SA <=スマSA ++ INT SA = 1)のための
		紫INVA =〜紫(SA)、寝室= 1。
		用(INT SB = 1; SB <= SUMB + 1; SB ++、睡眠* = INVA){ 
			紫V = F [CUR] [SA] [SB - 1] *スリープ- F [CUR] [SA] [SB] *(* INVAスリープ)。
			IF(VV){ 
				ANS - = V * SB * INVA *スマ。
			} 
		} 
	} 
	のprintf( "%d個の\ n"、ans.v)。
	0を返します。
}

問題点F二つの順列

  積極的に等しいまたは等しくない関係$ P_I、Q_Iを議論し、私は$。最小カット構成図、意味のスワップの一部を脇に置き、カットを考えてみましょう。そして、すべてのコストは$ Iに変換することができることを、私は」、S、T $が異なるカットセットに属しました。具体的に構築されたマップは、コードを見ることができます。

コード

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
ブールブールのtypedef。

constが(1〜0U >>)int型INF =(署名)に署名しました。

テンプレート<型名T> 
のボイドpfill(Tの*のPST、constのT *のPED、T val)で{ 
	のために(; PST = PED;!*(PST ++)= val)で、
} 

のtypedefクラスエッジ{ 
	パブリック:
		int型のED、NX、R。

		エッジ(INT ED = 0、INT NX = 0、INT R = 0):ED(ED)、NX(NX)、R(R){} 
}エッジ。

typedefのクラスMapManager { 
	パブリック:
		int型* hで、
		ベクトル<エッジ> ES; 

		MapManager(){} 
		MapManager(int型N){ 
			H =新しいINT [(N + 1)]。
			pfill(H、H + N + 1、-1)。
		} 
		〜MapManager(){ 
			[] Hを削除します。
			es.clear(); 
		} 

		ボイドaddEdge {(int型V、INT R UをINT)
			es.push_back(エッジ(V、H [U]、R)); 
			H [U] =(符号付き)es.size() - 1; 
		} 

		ボイドaddArc(INT U、int型V、INTキャップ){ 
			addEdge(U、V、キャップ)
			addEdge(V、U、0); 
		} 

		エッジ&演算子[](INT P){ 
			戻りES [P]。
		} 
} MapManager。

typedefのクラスのネットワーク{ 
	パブリック:
		int型S、T; 
		int型* CUR、* DIV。
		MapManagerのグラム。

		ネットワーク(){} 
		ネットワーク(INT S、int型T):S(S)、T(T)、G(T + 1){ 
			CUR =新しいINT [(T + 1)]。
			DIV =新しいINT [(T + 1)]。
		} 
		〜ネットワーク(){ 
			CUR []削除します。
			[] DIV削除します。
		} 

		ブールBFS(){ 
			静的キュー<整数> QUE。
			pfill(DIV、DIV + T + 1、-1)。
			DIV [S] = 0; 
			que.push(S)。
			(!que.empty()){ながら、
				int型E = que.front(); 
				que.pop(); 
				用(INT I = GH [E]、EU;〜I; I = G [i]が.nx){ 
// CERR << I << 'の\ n'; 
					もし(G [i]が.R!)
						続けます。
					EU = G [i]は.ED。
					もし(!〜DIV [EU]){ 
						DIV [EU] = divの[E] + 1; 
						que.push(EU)。
					} 
				} 
			} 
			〜DIV [T]を返します。
		} 

		INT DFS(INT P、INT MINF){ 
			IF(!P == T || MINF)
				リターンMINF。
			INT流量= 0、F。
			{(;(〜I)は、i = CUR [P]、I = G [i]が.nx INT&I = CUR [P]、E)のために
				E = G [i]は.ED。
				IF(DIV [E] == DIV [P] + 1 &&(F = DFS(例えば、分(MINF、G [i]は.R)))> 0){ 
					フロー+ = F。
					G [I]。R - = F。
					G [I ^ 1] .R + = F。
					MINF - = F。
					(!MINF){もし
						ブレーク。	
					} 
				} 
			} 
			戻り流。
		} 

		int型dinic(){ 
			int型RT = 0。
// CERR << GH [0] << '\ nの'; 
			(BFS()){ながら
				(; iが= Tを<I ++は、I = 0をINT)ため
					CUR [I] = GH [I]。
				RT + = DFS(S、INF)。
			} 
			RTを返します。
		} 
}ネットワーク。

CONST int型N = 1E5 + 5。

整数nを、T。
INT UF [N << 1]。
INT P [N]、Q [N]。

INT(INT X){見つける
	UF [X] == Xを返しますか?X:(UF [X] =(UF [X])を見つけます)。
} 
空隙部(INT X、int型のY){ 
	X =(X)を見つける、Y =(y)を見つけます。
	(x ^ y)の場合{ 
		UF [X] Yを=。
	} 
} 

int型のmain(){ 
	scanf関数( "%のD"、&N); 
	以下のために(INT i = 1; iが<= 2 * N; iは++)
		UF [I] = I。
	以下のために{(INT i = 1; iが++; iが<= N)
		のscanf( "%dの"、P + I)を、
		単位(I、++ P [I])。
	} 
	(i = 1 int型私は++; iが<= N)のために{ 
		scanf関数( "%のD"、Q + I)。
		ユニット(iは、Q ++、N + [I] + N)。
	} 
	ネットワーク・ネットワーク(0、T = 2 * N + 1)。
	MapManager&G = network.g。
	int型ANS = 0; 
	以下のために(INT i = 1; iが<= N; iは++){ 
		IF(I == P [i]は&& I == Q [I]){ 
			続けます。
		} 
		++ ANS。
		(!I = P [i]は&& I = Q [i]が!)なら、{ 
			g.addArc(1、(i)はN +を見つけ、(i)を見つけます。)。
		}そうでなければ(!私== P [i]は&& iは= Q [I]){もし
			g.addArc(0、(i)はN +を見つける、1)。
		}そうであれば(I = P [i]は&& I == Q [I]!){ 
			g.addArc(見つける(I)、T、1); 
		} 
		場合(P [I] == Qは[I]){ 
			g.addArc(1、(I)検索、(i)はN +を見つけます。)。
		} 
	} 
	ANS - =)(network.dinic。
	printf( "%d個の\ n"、ANS)。
	0を返します。
}

おすすめ

転載: www.cnblogs.com/yyf0309/p/11619680.html