https://codeforces.com/problemset/problem/367/C
タイトル
あなたにはm個の数があり、各数には無限の数があります。これらの数値を使用して、長さnの配列aを形成します。お願い
- 数xと数yが選択されている場合、2つの数は配列の少なくとも1つの位置で隣接します。iが存在するため、a [i] = xおよびa [i + 1] = y、またはa [i] = yおよびa [i + 1] = x
配列の値は、配列を構成する数値の値によって決まります。i番目の数値の値はv [i]です。
空の配列の値は0です。1からmまでのiを考慮してください。i番目の数値が表示される場合、配列の値は+ vになります[i]
配列の値を最大化するために配列を形成する方法を尋ねます
$ 1 \ leqslant n \ leqslant 2 \ times10 ^ 6、1 \ leqslant m \ leqslant 10 ^ 5 $
$ 1 \ leqslant v_i \ leqslant 10 ^ 5 $
解決策
選択した数値をグラフに描画します。すべての数値は2つのエッジを2つずつ接続する必要があり、問題はすべてのエッジを最小のステップで歩く方法です。
それからオイラーの質問になります
オイラー道路を形成するために必要かつ十分な条件は、次のとおりです。次数が奇数のポイントが最大で2つあり、残りは次数が偶数のポイントです。
オイラーループを形成するために必要かつ十分な条件は、すべての点が次数が等しい点であることです。
オイラー道路またはオイラー回路を形成できない場合は、隣接する数値が1回だけ出現する必要がなく、最後にシーケンスを取得できるため、エッジを追加する必要があります。
n個の数によって形成されるエッジの数は
\ [\ frac {n \ cdot(n-1)} {2} \]
各ポイントの次数は$ n-1 $です
nが奇数の場合、オイラーループを形成でき、配列の長さはエッジの数と等しくなります。
nが偶数の場合、すべてのポイントの次数は奇数になります。n> 2の場合、$ \ frac {n} {2} -1 $エッジを追加して、$ n-2 $ポイントの次数が+1になるようにする必要があります。偶数、オイラー道路を形成するためにn = 2の場合は0エッジを追加
これは、明らかに要件を満たす最小の長さの配列です。1つ少ない場合、すべてのエッジをトラバースすることはできません。1つ以上ある場合は、最小の長さであってはなりません。
だからあなたは$ O(m)$で最も多くの数を得ることができ、それから合計に貪欲です
時間の複雑さ$ \ mathcal {O}(m \ log m)$
ACコード
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define REP(i、a、b)for(int i =(a); i <(b); i ++) #define REPE(i、a、b)for(int i =(a); i <=(b); i ++) #define PERE(i、a、b)for(int i =(a); i> =(b); i--) 名前空間stdを使用します。 typedef long long ll; #define MAXM 100007 int arr [MAXM]; inline bool cmp(int a、int b){return a> b;} int main(){ int n、m; scanf( "%d%d"、&n、&m); REP(i、0、m)scanf( "%* d%d"、&arr [i]); sort(arr、arr + m、cmp); int ch = -1; ll ans = 0; PERE(x、m、1){ ll t = ll(x)*(x-1)/ 2; if((x&1)== 0)t + = x / 2-1; if(t <n){ch = x; break;} } REP(i、0、ch)ans + = arr [i]; printf( "%lld \ n"、ans); }