トピックリンク:
http://codeforces.com/contest/1248/problem/D2
質問の意味:
文字交換一回の操作を行うことができます
巡回シフトし、最も成功したマッチプログラムの後、このような文字列操作
プログラム番号と交換位置への出力アップ
データ範囲:
$ 1 \当量のn \の当量300 000 $
分析:
参考ブログ:https://www.cnblogs.com/LLTYYC/p/11718968.html
文字列の場合は、サイクリックシフトマッチングスキームの数を求めています
0から始まる行に文字列を有効にするには、遭遇した(プラスワンが発生した)、その後デクリメント
異なる(および)数は、明らかに答えが0であれば、そうでない場合、答えはポリラインYの最小の頂点の数であります
何が次に、全体的な上方シフトポリライン、最小値が0であるように、オフセットされてもよいです
破線は、答えがプラスの場合は0を返します。
次に検討する場合は、交換することができます
最初の折り線の上方シフト
回答は、回答数1又は交換されていない追加番号2、すなわち、最小値は-1、0であるか、または2つの操作方式の数を増加させる変更であります
前記数は共感の部分2の数、間隔1の最小値であります
ACコード:
#include <ビット/ STDC ++ H> の#defineは長い長いちゃう の#define PII対<整数、整数> 名前空間stdを使用します。 const int型MAXN = 3E5 + 7。 int型のn; チャーS [MAXN]。 int型のval [MAXN]。 INTメイン(){ scanf関数( "%のD"、&N); scanf関数( "%sの"、S + 1)。 = 0をオフにint型、ミネソタ州= 1E9; = 0になりましたint型。 以下のために(INT i = 1; iは= N <; iは++){ IF(S [I] == ')')now--。 他に今++; (ミネソタ州> NOW)場合{ ミネソタ=今。 オフ= I; } } もし(現在は!= 0){ のprintf( "0 \ N1 1つの\ n"); 0を返します。 } INT ANS = 0、ansl = 1、ANSR = 1、ANSS = 0。 {ため(iは++; iがn-1 = <I = 1 INT) ヴァル[I + 1] = valの[I]。 int型、V =(オフ+ I-1)%のN + 1。 IF(S [V] == ')')のval [I + 1] - 。 他のval [I + 1] ++; (valは[I] == 0)++ ANS場合。 // coutの<<ヴァル[I] <<」「; } // coutMM ANSS = ANS。 以下のために(INT i = 1; iが<= N + 1、iは++){ IF(ヴァル[I] == 2){ int型EN = I + 1、TEM = 1。 (ヴァル[EN]> = 2){ながら IF(ヴァル[EN] == 2)TEM ++。 エン++; } (TEM + ANSS> ANS){もし ANS = TEM + ANSS。 ansl =(iは+オフ-2 + N)%N + 1。 ANSR =(JA +オフ-2 + N)%N + 1。 } I =エン; } } のために(INT i = 1; iが<= N + 1、iは++){ // COUT <<ヴァル[I] <<」「。 IF(ヴァル[I] == 1){ int型EN = I + 1、TEM = 1。 (ヴァル[EN]> = 1){ながら IF(ヴァル[EN] == 1)TEM ++。 エン++; } IF(TEM> ANS){ ANS = TEM。 ansl =(iは+オフ-2 + N)%N + 1。 ANSR =(JA +オフ-2 + N)%N + 1。 } I = EN。 } } のprintf( "%d個の\ n%D%D \ n"は、ANS、ansl、ANSR)。 0を返します。 }