今日のAtcoderコンテストでD問題がACできませんでした、、。初めてD問題まで来たので悔しいです。条件通りの変数データ保持量になってるんですが、TLEになってしまいます。ですが、TLE以外はACしています。
https://atcoder.jp/contests/abc217/tasks/abc217_d
どなたかわかる方がいたらご教授お願いします。
C言語
1#include<stdio.h> 2int main(void){ 3 long long int q,c[20000000],x[20000000],min=0,min2=0,dai,tiisai,i,j; 4 long long int l; 5 scanf("%lld",&l); 6 scanf("%lld",&q); 7 for(i=1;i<=q;i++){ 8 scanf("%lld",&c[i]); 9 scanf("%lld",&x[i]); 10 } 11 min=l; 12 min2=l; 13 x[0]=l; 14 for(i=1;i<=q;i++){ 15 if(c[i]==2){ 16 for(j=0;j<i;j++){ 17 if(x[i]<x[j]&&min>x[j]-x[i]){ 18 min=x[j]-x[i]; 19 dai=x[j]; 20 } 21 if(x[i]>x[j]&&min2>x[i]-x[j]){ 22 min2=x[i]-x[j]; 23 tiisai=x[j]; 24 } 25 } 26 printf("%lld\n",dai-tiisai); 27 min=l; 28 min2=l; 29 x[i]=0; 30 dai=0; 31 tiisai=0; 32 } 33 34 } 35 return 0; 36}
何が知りたいのでしょうか。
TLEになる理由でしょうか。それとも、TLEを修正する方法でしょうか。
TLEになる理由は計算量がO(Q^2)だからですし、TLEを修正する方法は公式解説を見ればわかるでしょう。
知りたいのはTLEを修正する方法ですね、、。公式解説のアドバイスありがとうございます!ですが、公式解説はC++で行われているためよくわからないと言いますか、私の知識不足で申し訳ないです、、。良ければCでの解決方法を教えていただけますか?
それまでのxを保存し、次のxに最も近い前後の位置を"高速に"取り出せる機能が必要だ、と当たり前のことを言っている解説に思います。
C++なら使えるモノがあるのでこう書けるというだけです。
無ければ「平衡二分探索木やB-Tree」と呼ばれるものがお勧めという感じでしょうか。
正直、「平衡二分探索木やB-Tree」をC言語で実装するのは大変ですし、
検索してもすぐに使える実装は見当たらないので、こちらの方針での解決は難しいと思います。
他の人のC言語での回答を見るという手はありますが、私では解説できそうにありません。
https://atcoder.jp/contests/abc217/submissions?f.Task=abc217_d&f.LanguageName=C&f.Status=AC&f.User=
上記リンク先の一番下のソースは、「座標圧縮」と「セグメント木」が理解できれば、読めると思います。
試しにB-Treeで実装したところ、そこまで大変ではありませんでした(90行)。
「平衡二分探索木やB-Tree」について調べて、実装してみてはいかがでしょうか。
上記リンク先に、私のB-Treeによる作例や、他の方の平衡二分探索木による作例が追加されてるので、必要であれば参照してみてください。
大変、時間が空いてしまい申し訳ありませんでした、、。jimbeさん、actorbugさん回答ありがとうございます。actorbugさん、わざわざコードを書いてくださり、ありがとうございます。まだまだプログラミング能力は未熟だと身に沁みました。平衡二分探索木について全く知らなかったので、コードを確認しながら理解するとともに、身に付けていきたいと思います。
ぜひ、actorbugさんをベストアンサーにしたいのですが、ここに書いてくださったと同様に、URLを添付して回答していただけないでしょうか?お手数おかけします。
回答2件
あなたの回答
tips
プレビュー