Skip to content

Commit 43b7d25

Browse files
authored
Merge pull request #437 from Krishna200608/feature/issue-406-rudolf-snowflakes
Solved Issue #406: Rudolf and Snowflakes (Hard Version)
2 parents 7a10d4f + 628ed0d commit 43b7d25

1 file changed

Lines changed: 154 additions & 0 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*
2+
====================================================
3+
Problem: Rudolf and Snowflakes (Hard Version)
4+
Link: https://codeforces.com/contest/1846/problem/E2
5+
Author: Krishna Sikheriya (Krishna200608)
6+
====================================================
7+
8+
-------------------------
9+
Short Problem Statement
10+
-------------------------
11+
You are given an integer n.
12+
Your task is to determine whether n can be written as a geometric series:
13+
14+
n = 1 + k + k² + ... + kᵖ
15+
16+
where:
17+
- k ≥ 2 (the common ratio)
18+
- p ≥ 2 (so the series has at least 3 terms)
19+
20+
In simpler terms, check if n can be formed by summing powers of some integer k,
21+
starting from 1, with at least three terms.
22+
23+
-------------------------
24+
Approach (Length Fixing + Binary Search)
25+
-------------------------
26+
Key Observations:
27+
- The sum of a geometric series is:
28+
n = (k^(p+1) - 1) / (k - 1)
29+
- Since n ≤ 10¹⁸, the maximum possible exponent is small.
30+
For example, 2⁶⁰ already exceeds 10¹⁸.
31+
32+
Strategy:
33+
1. Fix the number of terms in the series (terms = p + 1).
34+
- Minimum terms = 3 (1 + k + k²)
35+
- Maximum terms ≈ 60 (because 2⁶⁰ > 10¹⁸)
36+
2. For a fixed number of terms:
37+
- The sum strictly increases as k increases.
38+
- This allows binary search over possible values of k.
39+
3. For each candidate k, compute the geometric sum safely.
40+
- Use __int128 to avoid overflow.
41+
- Stop early if the sum exceeds n.
42+
4. If any combination produces exactly n, output "YES".
43+
Otherwise, after all checks, output "NO".
44+
45+
-------------------------
46+
Time & Space Complexity
47+
-------------------------
48+
Time Complexity:
49+
- Outer loop over possible terms: O(log n)
50+
- Binary search on k: O(log n)
51+
- Total per test case: O((log n)²)
52+
53+
Space Complexity:
54+
- O(1), only constant extra space is used.
55+
56+
-------------------------
57+
Example I/O (Optional)
58+
-------------------------
59+
Input:
60+
9
61+
1
62+
2
63+
3
64+
6
65+
13
66+
15
67+
255
68+
27
69+
4805
70+
71+
Output:
72+
NO
73+
NO
74+
NO
75+
NO
76+
YES
77+
NO
78+
YES
79+
NO
80+
YES
81+
82+
-------------------------
83+
Submission Link
84+
-------------------------
85+
https://codeforces.com/contest/1846/submission/356083531
86+
====================================================
87+
*/
88+
89+
#include <bits/stdc++.h>
90+
using namespace std;
91+
92+
// Safely computes: 1 + k + k^2 + ... + k^(terms - 1)
93+
// If the sum exceeds 'limit', returns a value greater than limit
94+
__int128 geometric_sum(__int128 k, int terms, __int128 limit) {
95+
__int128 sum = 1;
96+
__int128 current = 1;
97+
98+
for (int i = 1; i < terms; i++) {
99+
// Prevent overflow while multiplying
100+
if (current > limit / k) return limit + 1;
101+
current *= k;
102+
103+
// Prevent overflow while adding
104+
if (sum > limit - current) return limit + 1;
105+
sum += current;
106+
}
107+
return sum;
108+
}
109+
110+
void solve() {
111+
long long n_input;
112+
cin >> n_input;
113+
__int128 n = n_input;
114+
115+
// Smallest valid snowflake: 1 + 2 + 4 = 7
116+
if (n < 7) {
117+
cout << "NO\n";
118+
return;
119+
}
120+
121+
// Try all possible lengths of the series (at least 3 terms)
122+
for (int terms = 3; terms <= 62; terms++) {
123+
long long low = 2;
124+
long long high = 2000000000LL; // Safe upper bound for k
125+
126+
while (low <= high) {
127+
long long mid = low + (high - low) / 2;
128+
__int128 val = geometric_sum(mid, terms, n);
129+
130+
if (val == n) {
131+
cout << "YES\n";
132+
return;
133+
} else if (val < n) {
134+
low = mid + 1;
135+
} else {
136+
high = mid - 1;
137+
}
138+
}
139+
}
140+
141+
cout << "NO\n";
142+
}
143+
144+
int main() {
145+
ios::sync_with_stdio(false);
146+
cin.tie(nullptr);
147+
148+
int t;
149+
cin >> t;
150+
while (t--) {
151+
solve();
152+
}
153+
return 0;
154+
}

0 commit comments

Comments
 (0)