結果
| 問題 |
No.151 セグメントフィッシング
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:06:41 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 19 ms / 5,000 ms |
| コード長 | 10,095 bytes |
| コンパイル時間 | 636 ms |
| コンパイル使用メモリ | 78,900 KB |
| 実行使用メモリ | 7,844 KB |
| 最終ジャッジ日時 | 2025-05-14 13:07:57 |
| 合計ジャッジ時間 | 1,792 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 5 |
| other | AC * 19 |
ソースコード
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // For min/max
using namespace std;
// Define long long type for large numbers, as fish counts can be up to 10^8
// and total counts can exceed 32-bit integer limits.
typedef long long ll;
// Using a vector for the Fenwick tree (BIT).
// It will store cumulative counts. Size will be N_COORD + 1 for 1-based indexing internally.
vector<ll> bit;
// N_COORD stores 2*N_val, which is the size of our coordinate space (0 to N_COORD-1).
// This coordinate space represents all possible states (position and direction) of a fish.
int N_COORD;
// Add 'val' to the element at index 'idx' (0-based) in the conceptual array.
// This function updates the Fenwick tree structure to reflect the change.
void add(int idx, ll val) {
// Convert to 1-based index because Fenwick trees are typically implemented with 1-based indexing.
idx++;
// Traverse up the tree structure by following the parent links (conceptually).
// Update all nodes that cover the range including 'idx'.
while (idx <= N_COORD) {
bit[idx] += val;
// `idx & (-idx)` gives the lowest set bit. Adding it moves to the next node.
idx += idx & (-idx);
}
}
// Query the prefix sum up to index 'idx' (0-based, inclusive).
// Returns the sum of elements from index 0 to idx in the conceptual array.
ll query(int idx) {
// Handle edge case where index is negative (e.g., querying up to a-1 when a=0).
if (idx < 0) return 0;
// Ensure index does not exceed bounds. If it does, clamp to the maximum valid index.
// query(N_COORD - 1) should return sum of all elements.
idx = min(idx, N_COORD - 1);
// Convert to 1-based index for BIT operations.
idx++;
ll sum = 0;
// Traverse down the tree structure (conceptually) by following links based on lowest set bit.
// Accumulate sums from relevant nodes.
while (idx > 0) {
sum += bit[idx];
// `idx & (-idx)` gives the lowest set bit. Subtracting it moves to the node representing the prefix ending just before this block.
idx -= idx & (-idx);
}
return sum;
}
// Query the sum of elements in the range [a, b) (0-based indices).
// Calculates sum of elements from index a up to (but not including) b.
ll range_query(int a, int b) {
// If the range is invalid or empty (a >= b), return 0.
if (a >= b) {
return 0;
}
// The sum over range [a, b) is equivalent to (sum up to b-1) - (sum up to a-1).
// query(idx) returns sum up to idx inclusive.
ll sum_b_minus_1 = query(b - 1);
ll sum_a_minus_1 = query(a - 1); // query handles idx=-1 correctly, returns 0.
// The range sum is the difference.
return sum_b_minus_1 - sum_a_minus_1;
}
// Custom modulo function to ensure the result is always non-negative.
// Standard C++ % operator can return negative results for negative inputs, which is problematic here.
ll mod(ll x, ll M) {
// `(x % M + M) % M` ensures result is in [0, M-1].
return (x % M + M) % M;
}
int main() {
// Use fast I/O operations to speed up input reading.
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N_val; // Input N: length of the fishing pond interval [0, N). Needs to be int because N <= 2*10^4.
int Q; // Input Q: number of queries. Needs to be int because Q <= 2*10^4.
cin >> N_val >> Q;
// The coordinate space size is 2 * N_val.
N_COORD = 2 * N_val;
// Initialize the Fenwick tree vector. Size N_COORD + 1 for 1-based indexing. All elements initialized to 0.
bit.resize(N_COORD + 1, 0);
// Process each query. Queries are indexed by time t from 1 to Q.
for (int t = 1; t <= Q; ++t) {
char type; // Type of query ('L', 'R', or 'C').
cin >> type;
if (type == 'L' || type == 'R') { // Fish release query (Add fish)
ll y, z; // Position 'y', number of fish 'z'. Both can be large potentially, use ll.
cin >> y >> z;
// Basic validation on position y based on problem constraints 0 <= y < N
// Though problem statement guarantees valid inputs, it's safe programming practice.
// if (y < 0 || y >= N_val) continue; // Skip invalid inputs if any
ll k_initial; // Variable to store the initial coordinate in our 0 to 2N-1 space.
if (type == 'L') {
// Fish starts at position y, moving Left.
// Coordinate mapping: N_val + (N_val - 1 - y).
// This maps states (pos, L) to the range [N, 2N-1].
k_initial = (ll)N_val + (N_val - 1 - y);
} else { // type == 'R'
// Fish starts at position y, moving Right.
// Coordinate mapping: y.
// This maps states (pos, R) to the range [0, N-1].
k_initial = y;
}
// Calculate the effective coordinate offset `k_offset`.
// This value represents the group's state normalized to time t=0.
// `k_offset = (k_initial - t) mod N_COORD`
// Fish released at time `t` with initial coordinate `k_initial` will have coordinate
// `(k_initial + (current_time - t)) mod N_COORD` at `current_time`.
// This is equivalent to `( (k_initial - t) + current_time ) mod N_COORD`.
// So `k_offset = (k_initial - t) mod N_COORD` acts as a phase offset.
ll k_offset = mod(k_initial - t, N_COORD);
// Add the 'z' fish to the count associated with this `k_offset` in the Fenwick tree.
add(k_offset, z);
} else { // type == 'C', Count query
ll y, z_query; // Query asks for fish count in the interval [y, z_query).
cin >> y >> z_query;
// Basic validation on query range [y, z_query).
// Constraints: 0 <= y < z_query <= N_val
// if (y < 0 || z_query > N_val || y >= z_query) { ... handle error or assume valid ... }
ll total_fish = 0; // Accumulator for the total fish count in the queried range.
// Fish positions are determined by their current coordinate `k_current`.
// `k_current = (k_offset + t) mod N_COORD`.
// A 'C' query asks for sum of fish counts `z` where the position `p` derived from `k_current` is in `[y, z_query)`.
// We need to find the set of `k_current` values that map to positions in `[y, z_query)`,
// then shift these ranges by `-t` to find the corresponding `k_offset` values to query in the BIT.
// Part 1: Count fish currently moving Right within the interval [y, z_query).
// Fish moving Right have coordinates `k_current` in [0, N_val - 1].
// Their position `p` is equal to `k_current`.
// We need `k_current` such that `y <= k_current < z_query`.
// Combined conditions: `y <= k_current < min(z_query, N_val)`.
// Target `k_current` interval: `[y, min(z_query, N_val))`.
ll a1 = y;
ll b1 = min((ll)z_query, (ll)N_val);
if (a1 < b1) { // Check if the interval is valid (non-empty).
// Calculate the shifted interval endpoints for `k_offset`. Shift by `-t`.
ll a1_shifted = mod(a1 - t, N_COORD);
ll b1_shifted = mod(b1 - t, N_COORD);
// Query the Fenwick tree over the shifted interval [a1_shifted, b1_shifted).
if (a1_shifted < b1_shifted) {
// If the interval does not wrap around modulo N_COORD.
total_fish += range_query(a1_shifted, b1_shifted);
} else {
// If the interval wraps around (e.g., [5, 2) in mod 10 means indices 5..9 and 0..1).
// Query the two parts separately: [a1_shifted, N_COORD) and [0, b1_shifted).
total_fish += range_query(a1_shifted, N_COORD); // Sum from a1_shifted to N_COORD-1
total_fish += range_query(0, b1_shifted); // Sum from 0 to b1_shifted-1
}
}
// Part 2: Count fish currently moving Left within the interval [y, z_query).
// Fish moving Left have coordinates `k_current` in [N_val, N_COORD - 1].
// Their position `p` is calculated as `p = N_COORD - 1 - k_current`.
// We need `k_current` such that `y <= p < z_query`.
// Substituting p: `y <= N_COORD - 1 - k_current < z_query`.
// Rearranging for `k_current` gives: `N_COORD - z_query <= k_current <= N_COORD - 1 - y`.
// Also `k_current` must be at least `N_val`.
// The combined coordinate range for `k_current`: `[max(N_val, N_COORD - z_query), N_COORD - y)`.
ll a2 = max((ll)N_val, (ll)N_COORD - z_query);
ll b2 = (ll)N_COORD - y;
if (a2 < b2) { // Check if the interval is valid (non-empty).
// Calculate the shifted interval endpoints for `k_offset`. Shift by `-t`.
ll a2_shifted = mod(a2 - t, N_COORD);
ll b2_shifted = mod(b2 - t, N_COORD);
// Query the Fenwick tree over the shifted interval [a2_shifted, b2_shifted).
if (a2_shifted < b2_shifted) {
// If the interval does not wrap around modulo N_COORD.
total_fish += range_query(a2_shifted, b2_shifted);
} else {
// If the interval wraps around.
// Query the two parts separately: [a2_shifted, N_COORD) and [0, b2_shifted).
total_fish += range_query(a2_shifted, N_COORD); // Sum from a2_shifted to N_COORD-1
total_fish += range_query(0, b2_shifted); // Sum from 0 to b2_shifted-1
}
}
// Print the final count for this 'C' query.
cout << total_fish << "\n";
}
}
return 0;
}
qwewe