結果
| 問題 |
No.3136 F,B in FizzBuzzString16
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-05-02 23:45:46 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,208 bytes |
| コンパイル時間 | 2,204 ms |
| コンパイル使用メモリ | 209,648 KB |
| 実行使用メモリ | 6,272 KB |
| 最終ジャッジ日時 | 2025-05-02 23:45:49 |
| 合計ジャッジ時間 | 3,607 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 WA * 3 |
| other | AC * 22 WA * 10 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
auto string16 = [&](long long x) -> string {
if(x%15 == 0) return "FizzBuzz";
else if(x%3 == 0) return "Fizz";
else if(x%5 == 0) return "Buzz";
string ret = "";
while(x){
long long r = x%16; x /= 16;
if(r < 10) ret += '0'+r;
else ret += 'A'+r-10;
}
reverse(ret.begin(),ret.end());
return ret;
};
auto findC = [&](long long L,long long R) -> tuple<long long,long long,long long> {
long long ret3 = R/3-(L-1)/3,ret5 = R/5-(L-1)/5,ret15 = R/15-(L-1)/15;
return {ret3-ret15,ret5-ret15,ret15};
};
auto findR = [&](long long x) -> pair<long long,long long> {
long long p16 = 1,d = 1;
while(true){
auto [f,b,fb] = findC(p16,p16*16-1);
x -= p16*15*d;
x += (f+b+fb)*d;
x -= f*4+b*4+fb*8;
if(x < 0){
x += f*4+b*4+fb*8;
x -= (f+b+fb)*d;
x += p16*15*d;
long long low = p16-1,high = p16*16;
while(high-low > 1){
long long mid = (high+low)/2;
tie(f,b,fb) = findC(p16,mid);
long long X = x;
X -= (mid-p16+1)*d;
X += (f+b+fb)*d;
X -= f*4+b*4+fb*8;
if(X < 0) high = mid;
else low = mid;
}
tie(f,b,fb) = findC(p16,low);
x -= (low-p16+1)*d;
x += (f+b+fb)*d;
x -= f*4+b*4+fb*8;
return {low,x};
}
p16 *= 16,d++;
}
};
vector<long long> P16(100,1);
for(int i=1; i<100; i++) P16.at(i) = P16.at(i-1)*16;
vector<vector<tuple<long long,long long>>> memo(100,vector<tuple<long long,long long>>(16,{-1,-1}));
auto count = [&](auto count,long long d,long long r) -> tuple<long long,long long> {
if(d < 0) return {0,0};
if(get<0>(memo.at(d).at(r)) != -1) return memo.at(d).at(r);
if(d == 0){
if(r%15 == 0) return {2,1};
if(r%3 == 0 || r%5 == 0) return {1,1};
return {0,0};
}
long long ret = 0,ret2 = 0,memor = r;
for(int i=0; i<16; i++){
auto [add,minus] = count(count,d-1,r);
ret += add; ret2 += minus;
if(i == 11 || i == 15) ret += P16.at(d-1)-minus;
r = (r+1)%15;
}
memo.at(d).at(memor) = {ret,ret2};
return {ret,ret2};
};
auto solve = [&](long long x) -> long long {
if(x == 0) return 0;
auto [R,more] = findR(x);
long long ret = 0;
long long p16 = 1,d = 0; x = R;
while(R >= p16*16){
p16 *= 16; d++;
auto [add,minus] = count(count,d,1);
ret = add;
}
long long start = p16;
while(d >= 0){
for(int i=0; i<16; i++){
if(start+p16-1 > R) break;
string s = string16(start);
if(s.back() == 'z'){
s = string16(start+1);
if(s.back() == 'z') s = string16(start+2);
s.back() = '0';
}
long long one = 0;
for(auto c : s) one += (c=='F')|(c=='B');
if(p16 > 1){
auto [add,minus] = count(count,d,start%15);
ret += add;
ret += (p16-minus)*one;
}
else{
s = string16(start);
one = 0;
for(auto c : s) one += (c=='F')|(c=='B');
ret += one;
}
start += p16;
}
p16 /= 16,d--;
}
{
string last = string16(R+1);
for(int i=0; i<more; i++) ret += (last.at(i)=='F')|(last.at(i)=='B');
}
return ret;
};
long long X,Y; cin >> X >> Y;
cout << solve(Y)-solve(X) << endl;
}