質問の意味:
列数、数字内の$ 1構築〜スコープN $、$ /和^要件{N} _ {I}カウント(I)^ {2} $最小、$カウント(I)$ Iの列の数を意味します出現数。そして、条件の2種類の列の数が満たされている、一つは$ a_i-> a_j $すべてのVより大きく、同様に$ a_i-> a_j $など、すべて未満のVです。
アイデア:
まず第一に、我々は、上部及び特定の位置の下限値に制約を置くことができ、その後、位置は、建物の容量の両側に対応する全ての数字を入力し、その後の1をシンクするためのN個のデジタル建物容量のそれぞれができます側、一つは......、2 * J-1 $、$ 1,3,5の原価計算、その数は二回選択し、ちょうど取得した場合、建設側の後、プレフィックスは出現数の二乗です。
#pragma GCCの最適化(2) の#pragma G ++最適化(2) の#pragmaコメント(リンカー、 "/ STACK:102400000,102400000") の#include <ビット/ STDC ++ H> の#include <cstdioを> する#include <ベクトル> の#define担当者(iは、、B)のための(iは= int型、iが<= bは、iが++) の#define DEP(I、B、A)(iはBを= int型;方には> =; i--) の#define CLR(B)のmemset(A、B、はsizeof(A)) の#define PB一back の#define PII対<整数、整数> 使用して 名前空間STDを、 typedefの長い 長いLL。 const int型 MAXN = 200010 ; CONST int型 INF = 0x3f3f3f3f 。 LL RD() { LL、X = 0、F = 1。チャー CH = GETCHAR()。 一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ')、F = - 1 ; CH = GETCHAR();} 一方(CH> = ' 0 ' && CH <= ' 9 '){X = X * 10 + CH- ' 0 ' ; CH = GETCHAR();} リターンのx *のF; } の#include <ビット/ STDC ++ H> の#define CLR(B)のmemset(A、B、はsizeof(a))が 使用 名前空間STDを、 typedefの長い 長いLL。 const int型 MAXN = 1010 ; const int型 MAXM = 20010 ; const int型 INF = 0x3f3f3f3f 。 構造体のエッジ{ INT 、次に、キャップ、流れ、コストに、 }エッジ[MAXM]。 構造体PP { int型、U、V、C、W。 } で【MAXN]。 int型ヘッド【MAXN]、TOL。 INT プレ[MAXN]、[MAXN] DIS。 BOOL VIS [MAXN]。 INT N = MAXN- 2 。 INTのN、Q、L [MAXN]、R [MAXN]。 ボイドのinit(){ TOL = 0 。 memsetの(頭、 - 1、はsizeof (ヘッド))。 } ボイド ADDV(INT U、INT V、int型のキャップ、int型のコスト){ エッジ[TOL] .TO = V。 エッジ[TOL]の.cap = キャップ。 エッジ[TOL] .cost =コスト。 エッジ[TOL] .flow CLR(DIS、INF)。= 0 ; エッジ[TOL] .next = 頭部[U]。 ヘッド[U] = TOL ++ 。 エッジ[TOL] .TO = U。 エッジ[TOL]の.cap = 0 。 エッジ[TOL] .cost = - コスト。 エッジ[TOL] .flow = 0 。 エッジ[TOL] .next = 頭部[V]。 ヘッド[V] = TOL ++ 。 } BOOL spfa(INT S、INT T){ キュー < INT > Q。 CLR(VIS、0)、CLR(プリ、 - 1)。 DIS [S] = 0 ; VIS [S] = 真。 q.push(S); しばらく(!q.empty()){ int型のu = q.front(); q.pop(); VIS [U] = 偽; 以下のために(int型 - ;!I = I =ヘッド[U] 1 ; I = {エッジ[I] .next) のint V = エッジ[I] .TO。 もし(エッジ[I]の.cap>エッジ[I] .flow && DIS [V]> DIS [U] + エッジ[I] .cost){ DIS [V] = DIS [U] + エッジ[I] .cost ; [V]事前 = ; I IF(!{VIS [V]) VIS [V] = trueに; ; q.push(V) } } } } IF - (PRE [T] == 1)リターン falseにし、 他の リターン 真へ; } // 最大流量を返し、最小のコストがコスト格納されている INT minCostMaxflow(INT S、INT T、INT&コスト){ int型の流量=。0 コスト = 0 。 一方、(spfa(S、T)){ int型最小= INFと、 用(int型 - ;!I = I =事前[T] 1 ; I =事前[エッジ[I ^ 1 {] .TO]) であれば( -最小>エッジ[I]の.cap [i]は.flowエッジ)を 最小 =エッジ[I]の.cap - エッジ[I] .flow。 } のための(int型 I =事前[T]; I =! - 1 ; I =事前[エッジ[I ^ 1 ] .TO]){ エッジ[I] .flow + = 分; エッジ[I ^ 1] .flow - = 分; コスト [I] .cost * + =縁分; } フロー + = 分; } 戻り流; } int型のmain(){ CIN >> N >> Q。 初期化(); INT S = 0、T = 2 * N + 1 。 担当者(I、1 、N){ ADDV(S、I、1、0 ); R [I] = N。 L [I] = 1 。 担当者(J、1 、N){ ADDV(I+ N、T、1、2 * J- 1 )。 } } int型フラグ= 1 。 一方、(q-- ){ int型のOP、X、Y、V。 scanf関数(" %D%D%D%D "、&OP、およびX&Y、およびV)。 もし(OPの== 1 ){ 担当者(I、x、y)は{ L [I] = MAX(L [i]は、V)。 } } 他{ 担当者(I、x、y)は{ R [I] = 分(R [i]は、V)。 } } } 担当者(I、1 、N){ 場合(L [I]> R [I]){ フラグ = 0 。 破ります; } 担当者(J、L [i]は、R [I]){ ADDV(I、J + N、1、0 ); } } もし(フラグ== 0 ){ プット(" -1 " )。 リターン 0 ; } int型C。 minCostMaxflow(S、T、C)。 coutの << C << てendl; }