リンク:パーフェクトトリプル
一見すると、この質問は気が狂っているようです。
何も考えずに、ちょっとしたルールを見つけました。
a <b <c。そして、bの最大のバイナリビットは、abの最大のバイナリビットがcと等しくなければならないよりも厳密に大きい必要があります。
しかし、これは問題の解決には役立ちません。
リストを作成して、パターンがあるかどうかを確認することを検討してください。
この質問を通して、私は時計を見るための法律を見つけることも技術的な仕事であることを認めます。
2行目のaの値は増加していることがわかりますが、前のいくつかを考慮すると、aをすぐに見つけることができます。
しかし、bとcはまだ見つけるのが難しいです。その後、次のルールを遵守してください。
私の失敗はまた、ここでの法則が一般に小さいデータと一貫しているという事実が原因であり、これらの値1〜15を満たさなくても意味がありません。
10分で検索して失敗しましたが、4はグループとしてはほとんど見えませんでしたが、bとcのルールを見つけるのはまだ困難でした。すぐに見つけることができません。
しかし、これは試験ではなく、自分をシャットダウンする必要はありません。
問題解決策をひっくり返すと、問題解決策はより厳しいルールを与えました。
これは、ノードとして3つの数値を持つ四分木です。
この四分木を描くことを考えると、あなたの息子と父親が素晴らしいつながりを持っていることに気付くと驚くかもしれません。
最初のノード(1,2,3)と最初の息子(4,8,12)をよく見てください。
前者のバイナリビットを左にシフトして後者を取得するだけです。
最初のノードの2番目の息子が、最初の息子に(1,2,3)を追加することによって明らかに得られることを考慮してください。3番目の息子は、最初の息子に(2、3、1)を追加することによって取得されます。4番目の息子は、最初の息子に(3,1,2)を追加することによって取得されます。
この時点で、ルートノードからずっと下まで直接検索できます。これは四分木であるため、各クエリはlog4(n)複雑です。
この質問は、法律は小さな場所から見出されるべきであり、一般的に小さな数のセットに当てはまることを教えてくれます。見やすいです。
実際、この出力は、20分yyのうちの1つの方法を思い起こさせるのが非常に困難です。
父親を特定するのは難しすぎます。
これはレイヤプレフィックスの形式であり、レイヤが最初に配置されていることがわかります。これは接頭辞を使用してエンゲージできます。
その後、あなたはあなたの父親の立場を見つけ、あなたの立場を父親の長男に変えることができます。
これにより、上から下まで簡単に行うことができます。これはエラーを特定する可能性が高いプレフィックスの形式であるため、父親を直接特定する方法は間違っていることに注意してください。
const ll MAXN=100010;
ll n,T,top;
ll s[MAXN],a,b,c;
ll p[MAXN],maxx,sum[MAXN];
int main()
{
freopen("1.in","r",stdin);
get(T);p[0]=1;maxx=27;sum[0]=1;
rep(1,maxx,i)p[i]=p[i-1]*4,sum[i]+=sum[i-1]+p[i];
//putl(sum[maxx]);
while(T--)
{
get(n);top=0;
ll ww=(n-1)/3+1;
ll cc=n%3==0?3:n%3;
ll w1=0;
while(sum[w1]<ww)++w1;
ww=ww-(w1==0?0:sum[w1-1]);
while(w1)
{
ll p1=(ww-1)/4+1;
s[++top]=ww-(p1-1)*4;
ww=p1;--w1;
}
a=1;b=2;c=3;
while(top)
{
a=a<<2;b=b<<2;c=c<<2;
if(s[top]==2)a+=1,b+=2,c+=3;
if(s[top]==3)a+=2,b+=3,c+=1;
if(s[top]==4)a+=3,b+=1,c+=2;
--top;
}
if(cc==1)putl(a);
if(cc==2)putl(b);
if(cc==3)putl(c);
}
return 0;
}