700点3問

C - Sequence Growing Easy

C - Sequence Growing Easy

問題:すべて0の数列XのX(i+1)=Xi+1にする操作を好きなだけできる。数列Aiを実現する最小操作回数を求めよ

 

考察:

逆順に見ます。

操作:Ai+1==A(i+1)のとき、A(i+1)を好きな要素に変える。

全て0にしたい。

 

もしA(i+1)>=Ai+2のとき実現不可能です。

順にAi以前の要素を多くしたとしても、最後は0,2などとなり、0を増やすことはできないので不可能です。

 

よって増加する場合は+1の必要があります。

また、A0==0の必要があります。

 

Ai>=A(i+1)であるときを考えます。

このときAiをA(i+1)-1に置き換える必要があります。これが1以上のときは操作を2回必要とすることがわかります。なぜならA(i+1)-1にしたあと0にする操作が必要だからです。

 

このことを踏まえると、A(i+1)回操作が加わることになります。

以上を実装すればよいです。

 

 

 

E - Connected?

E - Connected?

問題:x方向[0,r]、y方向[0,c]の範囲の長方形の周上含む内部に2n個の点がある。2*iと2*i+1個目の点を曲線で結ぶ。長方形の外に曲線がでないように、またn本の曲線が交わらないように結ぶことはできるか。

 

 

考察:

まず、両方が周上にある場合だけを考えればよいです。

 

周上と隙間がある場合そこを通って結ぶことが可能です。

 

1周して順に何番目の頂点かを並べます。このときxyxyの並びになっていたら不可能です。

同じ組が隣接していれば必ず結ぶことができます。その後その頂点対は考えなくてよいです。

 

前から要素を追加していき、1つ前の要素と一致すればpopします。

最後に残った要素が2より大きい場合NOです。

 

vectorで簡単に実装可能です。

 

 

 

 

 

 

E - guruguru

E - guruguru

問題:明るさは1,2、…m、1と循環で1ずつ変えられる。またお気に入りの値xに1回で変えられる。a1からanまで順に明るさを変えたいとき、操作回数を最小化するxを決め、操作回数を求めよ

 

 

考察:

まず後者の操作を無視して考えます。

 

この時各操作で

a[i] => a[i+1]

a[i] => a[i+1] + m

の2通りが考えられます。

 

x=a[i] + 2のとき2回かかる操作が1回になるので1回得します。

この要領で考えるとあるxベクトルを考え、a[i] => a[i+1]について

区間[a[i]+2,a[i+1]] に 1,2、…を足すというクエリを処理します。

このxの最大値分、操作を削減することができます。

 

このクエリ処理問題に帰着できました。

これはイベント処理のように解くことができます。

 

はじめにクエリを始点の昇順に並べておきます。

そして1~2mまで見ていくとき、いま所持するクエリの数と、いまある効用の大きさを持ちます。また、各クエリの(終点、長さ)を終点の昇順で持ちます。

以下のアルゴリズムを実行します。

 

1:始点と一致するようなクエリ分、所持数を増やす。

2:所持してるクエリの数、効用を増やす。

3:終点に達しているなら、効用から長さを引く

 

各ステップでx[i%m]に効用を足せばよいです。

 

 

 

以上でO*1で解くことができました。

 

実装かなりキツめでしたが、通せてうれしかったです。

*1:M+N)log(N