結果
問題 |
No.3053 $((0 \And 1)\mathop{|}2)\oplus 3$
|
ユーザー |
|
提出日時 | 2025-01-20 00:26:53 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 59 ms / 2,000 ms |
コード長 | 1,863 bytes |
コンパイル時間 | 4,520 ms |
コンパイル使用メモリ | 252,444 KB |
実行使用メモリ | 16,160 KB |
最終ジャッジ日時 | 2025-03-08 00:10:42 |
合計ジャッジ時間 | 6,217 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 35 |
ソースコード
#include<bits/stdc++.h> #include<atcoder/all> using namespace std; using mint=atcoder::modint998244353; int main(){ string s; cin>>s; int n=s.size(); vector<mint> ppw2(n+1),ppw3(n+1); ppw2[0]=2,ppw3[0]=3; for(int i=1;i<=n;i++) ppw2[i]=ppw2[i-1]*ppw2[i-1],ppw3[i]=ppw3[i-1]*ppw3[i-1]; vector<mint> ippw2(n+1); ippw2[0]=mint(2).inv(); for(int i=1;i<=n;i++) ippw2[i]=ippw2[i-1]*ippw2[i-1]; mint prod2=1,prod3=1; for(int i=0;i<n;i++) if(s[i]=='1') prod3*=ppw3[n-i-1],prod2*=ppw2[n-i-1]; mint ans=0,inv9=mint(9).inv(),pw2=mint(2).pow(n-1),prod=1; prod3*=mint(3).inv(); for(int i=0;i<n;i++){ if(s[i]=='1'){ ans+=prod3*pw2*mint(2); prod*=ppw3[n-i-1]*ippw2[n-i-1]; }else{ ans+=prod*prod2*mint(4)*inv9*pw2; } pw2*=ippw2[0]; } cout<<ans.val()<<endl; } /* leading zeroなしありがとう... 寄与に分解してください。 i bit目について、 後ろから定めて、ORが現れると解放される感じではありそうだけど、詰めてこう Nのbitが1の時、ORだと終了、ANDだとN-1までが1という条件になって、XORだとN-1までが0という条件になる。(後ろ二つは、合わせて3^(N-1)なので、2*3^(N-1)) Nのbitが0の時、OR→N-1までが1、AND→×、XOR→N-1までが1なので、2*(N-1の問題)になってる これは、そのbitが0である間繰り返されて、1になったらbitが1のケースになるので、1になる最大整数をxとして2^(N-x+1)*3^(x-1)=2^N*(3/2)^(x-1) このようなxは0...01...10...01...1.....という感じになるから、0から数えて2^(i+1)*floor(N/2^(i+1))個目。よって、x=2^(i+1)*floor(N/2^(i+1))-1 あとは頑張ってくださいという感じではある。指数ちょっと困るねぇ... 2^(N+2)/9*(3/2)^(2^(i+1)*floor(N/2^(i+1)))にすると、もうちょいなんとかなりそうではある なる。 */