QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#638321 | #9225. Fibonacci Fusion | propane# | WA | 30ms | 7436kb | C++20 | 5.0kb | 2024-10-13 15:38:22 | 2024-10-13 15:38:24 |
Judging History
answer
#include<iostream>
#include<cstring>
#include<vector>
#include<iomanip>
#include<algorithm>
#include<numeric>
#include<unordered_set>
#include<unordered_map>
using namespace std;
using LL = long long;
const int BASE = 1e9, WIDTH = 9;
using BigInt = vector<int>;
BigInt operator+(const BigInt &a, const BigInt &b){
BigInt c(max(a.size(), b.size()) + 1);
for(int i = 0; i < (int)a.size(); i++){
c[i] += a[i];
}
for(int i = 0; i < (int)b.size(); i++){
c[i] += b[i];
}
for(int i = 0; i < (int)c.size(); i++){
if (c[i] >= BASE){
c[i + 1] += 1;
c[i] -= BASE;
}
}
while(c.size() > 1 && c.back() == 0){
c.pop_back();
}
return c;
}
BigInt operator-(const BigInt &a, const BigInt &b){
BigInt c(max(a.size(), b.size()));
for(int i = 0; i < (int)a.size(); i++){
c[i] += a[i];
}
for(int i = 0; i < (int)b.size(); i++){
c[i] -= b[i];
}
for(int i = 0; i < (int)c.size(); i++){
if (c[i] < 0){
c[i + 1] -= 1;
c[i] += BASE;
}
}
while(c.size() > 1 && c.back() == 0){
c.pop_back();
}
return c;
}
BigInt operator*(const BigInt &a, int b){
BigInt c(a.size() + 1);
long long t = 0;
for(int i = 0; i < (int)a.size(); i++){
t += 1LL * a[i] * b;
c[i] = t % BASE;
t /= BASE;
}
c.back() = t;
while(c.size() > 1 && c.back() == 0){
c.pop_back();
}
return c;
}
pair<BigInt, long long> operator/(const BigInt &a, int b){
BigInt c;
c.reserve(a.size());
long long r = 0;
for(int i = (int)a.size() - 1; i >= 0; i--){
r = r * BASE + a[i];
c.push_back(r / b);
r %= b;
}
reverse(c.begin(), c.end());
while(c.size() > 1 && c.back() == 0){
c.pop_back();
}
return {c, r};
}
bool operator<(const BigInt &a, const BigInt &b){
if (a.size() != b.size()){
return a.size() < b.size();
}
for(int i = (int)a.size() - 1; i >= 0; i--){
if (a[i] != b[i]){
return a[i] < b[i];
}
}
return false;
}
BigInt str2int(const string &s){
BigInt a;
a.reserve(s.size() / WIDTH + 1);
int base = 1, val = 0;
for(int i = (int)s.size() - 1; i >= 0; i--){
val += (s[i] - '0') * base;
base *= 10;
if (base == BASE){
a.push_back(val);
base = 1, val = 0;
}
}
if (a.empty() || val) a.push_back(val);
return a;
}
ostream &operator<<(ostream &os, const BigInt &A) {
os << A.back();
for(int i = (int)A.size() - 2; i >= 0; i--)
os << setw(WIDTH) << setfill('0') << A[i];
return os;
}
const int N = 5000;
BigInt fib[N + 5];
int fib1[N + 5], fib2[N + 5];
const int mod1 = 1e9 + 7, mod2 = 998244353;
int main(){
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
fib[1] = str2int("1");
fib[2] = str2int("2");
fib1[1] = fib2[1] = 1;
fib1[2] = fib2[2] = 2;
for(int i = 3; i <= N; i++){
fib[i] = fib[i - 2] + fib[i - 1];
fib1[i] = (fib1[i - 2] + fib1[i - 1]) % mod1;
fib2[i] = (fib2[i - 2] + fib2[i - 1]) % mod2;
}
int n;
cin >> n;
vector<BigInt> a(n);
vector<int> a1(n), a2(n);
for(int i = 0; i < n; i++){
string s;
cin >> s;
a[i] = str2int(s);
int v1 = 0, v2 = 0;
for(auto c : s){
v1 = (v1 * 10LL + c - '0') % mod1;
v2 = (v2 * 10LL + c - '0') % mod2;
}
a1[i] = v1;
a2[i] = v2;
}
vector<int> id(n);
iota(id.begin(), id.end(), 0);
sort(id.begin(), id.end(), [&](int x, int y){
return a[x] < a[y];
});
auto get = [&](int v1, int v2){
return 1LL * v1 * (1000'000'009) + v2;
};
unordered_set<LL> s;
for(int i = 1; i <= N; i++){
s.insert(get(fib1[i], fib2[i]));
}
LL ans = 0;
unordered_map<LL, int> mp;
for(int i = 0; i < n; i++){
int x = id[i];
if (fib[N - 2] < a[x]){
for(int j = 0; j < i; j++){
int v1 = (a1[id[j]] + a1[x]) % mod1;
int v2 = (a2[id[j]] + a2[x]) % mod2;
if (s.contains(get(v1, v2))){
ans += 1;
}
}
}
else{
int rk = lower_bound(fib + 1, fib + N + 1, a[x], [&](auto &&a, auto &&b){
return a < b;
}) - fib;
for(auto y : {rk, rk + 1}){
int v1 = (fib1[y] - a1[x] + mod1) % mod1;
int v2 = (fib2[y] - a2[x] + mod2) % mod2;
if (mp.contains(get(v1, v2))){
ans += mp[get(v1, v2)];
}
}
}
mp[get(a1[x], a2[x])] += 1;
}
cout << ans << '\n';
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 5388kb
input:
6 50 8 8 5 72 354224848179261915070
output:
4
result:
ok 1 number(s): "4"
Test #2:
score: -100
Wrong Answer
time: 30ms
memory: 7436kb
input:
28 200878223506436882933619847964496455022155117513398820563747455993172799881403389571477889821109288771413214004090719097929400406252135763028179112130390003528046316900603668569910008417315162907579003880220844686222148696041857432602133894827753998572080650383305777912447151917272483538029469449...
output:
0
result:
wrong answer 1st numbers differ - expected: '27', found: '0'