USACO 2016 December · Silver · all three problems
Problem 1 — Counting Haybales
Statement
Farmer John has N haybales at integer positions on a 1D road. Answer Q queries: for each [A, B], output the number of haybales x with A ≤ x ≤ B.
Constraints
- 1 ≤ N, Q ≤ 105.
- Haybale positions and query endpoints are integers in [0, 109].
- Positions are distinct.
- Time limit: 2s. Memory limit: 256 MB.
Key idea
Sort the haybale positions once. For a query [A, B] the answer is upper_bound(B) − lower_bound(A) on the sorted array — i.e. the count of indices i with pos[i] ∈ [A, B].
Complexity target
O((N + Q) log N): one sort, two binary searches per query.
Reference solution (C++)
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int N, Q; cin >> N >> Q;
vector<int> pos(N);
for (auto& x : pos) cin >> x;
sort(pos.begin(), pos.end());
while (Q--) {
int a, b; cin >> a >> b;
auto lo = lower_bound(pos.begin(), pos.end(), a);
auto hi = upper_bound(pos.begin(), pos.end(), b);
cout << (hi - lo) << "\n";
}
}
Pitfalls
- Inclusive on both ends. Use
lower_boundfor A (≥ A) andupper_boundfor B (> B). - Don't forget to sort. Input order is arbitrary; the binary searches require sorted data.
- Positions fit in
intat 109, but the answer is bounded by N, also fine forint. - Use fast I/O. 105 queries with cin/cout without
sync_with_stdio(false)may TLE.
Problem 2 — Cities and States
Statement
N cities are given, each with a name (≥ 2 letters) and a 2-letter state code. Two cities (Ci, Si) and (Cj, Sj) form a "special pair" if the first two letters of Ci equal Sj, the first two letters of Cj equal Si, and the states are different (Si ≠ Sj). Count unordered special pairs.
Constraints
- 1 ≤ N ≤ 2 · 105.
- City names have ≥ 2 uppercase letters; state codes are 2 uppercase letters.
- Answer fits in 64-bit.
- Time limit: 2s. Memory limit: 256 MB.
Key idea
Reduce each city to the ordered pair (prefix2, state). Two cities (Pi, Si) and (Pj, Sj) form a special pair iff Pi = Sj, Pj = Si, and Si ≠ Sj. Bucket cities by (prefix2, state) in a hashmap. For each city in bucket (P, S) the number of partners is the count of bucket (S, P) — except we must exclude entries where the partner has the same state (i.e. S = P, which would also kill the different-state condition; equivalently subtract the count of bucket (P, P) when P = S). Sum and divide by 2 for unordered pairs.
Complexity target
O(N) using an unordered_map keyed by a 4-character code (encode as a 32-bit int).
Reference solution (C++)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int N; cin >> N;
// Encode (prefix2, state) as a 4-letter code -> integer.
auto enc = [](const string& a, const string& b) {
return ((a[0] - 'A') * 26 + (a[1] - 'A')) * 676
+ ((b[0] - 'A') * 26 + (b[1] - 'A'));
};
vector<int> codes(N), prefkey(N), statekey(N);
unordered_map<int, int> cnt;
cnt.reserve(N * 2);
for (int i = 0; i < N; ++i) {
string c, s; cin >> c >> s;
string p = c.substr(0, 2);
codes[i] = enc(p, s);
cnt[codes[i]]++;
// Save P and S as 0..675 integers for the swap lookup.
prefkey[i] = (p[0] - 'A') * 26 + (p[1] - 'A');
statekey[i] = (s[0] - 'A') * 26 + (s[1] - 'A');
}
ll ans = 0;
for (int i = 0; i < N; ++i) {
if (prefkey[i] == statekey[i]) continue; // P == S can't pair (same-state)
int swapped = statekey[i] * 676 + prefkey[i]; // bucket (S, P)
auto it = cnt.find(swapped);
if (it != cnt.end()) ans += it->second;
}
cout << (ans / 2) << "\n";
}
Pitfalls
- Same-state exclusion. Cities with prefix == state can never participate — easy to forget when iterating partners.
- Divide by 2 once at the end. Each pair is counted twice (once from each side).
- Watch
unordered_maphash attacks. Use an integer encoding to keep the map cheap; avoid string keys for 2·105 lookups. - 64-bit answer. Worst case is ~N² /(some constant) which exceeds 231.
Problem 3 — Moocast
Statement
N cows have walkie-talkies with individual transmission powers Pi. Cow i can directly send a message to cow j if the Euclidean distance between them is at most Pi (one-way, since Pj may be smaller). Messages can be relayed. For each cow as the originator, find how many cows the message can reach; output the maximum over all starting cows.
Constraints
- 1 ≤ N ≤ 200.
- Coordinates and powers are integers up to 25 000.
- Time limit: 2s. Memory limit: 256 MB.
Key idea
Build a directed reachability graph: edge i → j iff dist²(i, j) ≤ Pi². With N ≤ 200 the graph has at most 40 000 edges. For each source run BFS/DFS and count reached nodes; report the maximum. Compare squared distances to avoid floating point.
Complexity target
O(N · (N + E)) = O(N³) ≈ 8 · 106. Plenty of room.
Reference solution (C++)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int N; cin >> N;
vector<ll> x(N), y(N), p(N);
for (int i = 0; i < N; ++i) cin >> x[i] >> y[i] >> p[i];
// adj[i] = cows j such that cow i can directly send to j (dist^2 <= p[i]^2).
vector<vector<int>> adj(N);
for (int i = 0; i < N; ++i) {
ll P2 = p[i] * p[i];
for (int j = 0; j < N; ++j) if (j != i) {
ll dx = x[i] - x[j], dy = y[i] - y[j];
if (dx * dx + dy * dy <= P2) adj[i].push_back(j);
}
}
int best = 0;
for (int s = 0; s < N; ++s) {
vector<char> seen(N, 0);
queue<int> q; q.push(s); seen[s] = 1;
int cnt = 0;
while (!q.empty()) {
int u = q.front(); q.pop(); ++cnt;
for (int v : adj[u]) if (!seen[v]) { seen[v] = 1; q.push(v); }
}
best = max(best, cnt);
}
cout << best << "\n";
}
Pitfalls
- Directed edges. Edge i → j does not imply j → i because the powers differ.
- Avoid
sqrt; compare dx² + dy² against P². Coordinates up to 25 000 give squares up to ~6 · 108, fits inlong long. - Count the source. The problem says the message includes the originating cow.
- Don't try Floyd-Warshall transitive closure as a 200×200 bitset — easier, but the straightforward BFS-from-each-source is the Silver-level path.
What Silver December 2016 was actually testing
- P1 — sorted array + binary search. Use
lower_bound/upper_bound. - P2 — hashmap counting with swap-symmetry. Reduce records to (prefix, state) keys, look up the swapped bucket, divide by 2.
- P3 — BFS on a directed reachability graph. N is small enough that source-by-source BFS is the intended O(N³).