結果

問題 No.265 数学のテスト
ユーザー qwewe
提出日時 2025-05-14 13:16:44
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 6 ms / 2,000 ms
コード長 10,426 bytes
コンパイル時間 892 ms
コンパイル使用メモリ 76,504 KB
実行使用メモリ 7,844 KB
最終ジャッジ日時 2025-05-14 13:18:34
合計ジャッジ時間 2,075 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 32
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <string>
#include <numeric>
#include <cctype> // Use <cctype> for C++ standard library functions like isdigit

// Using standard namespace for convenience
using namespace std;

// Global variable for maximum degree d specified in input.
// The polynomial vector will have size D_MAX + 1, storing coefficients for x^0 to x^D_MAX.
int D_MAX; 

// Type alias for Polynomial using vector of long long coefficients.
// Index i corresponds to the coefficient of x^i.
// We use long long to accommodate potentially large coefficients.
using Polynomial = vector<long long>;

// Creates a polynomial representing a constant c.
// P(x) = c * x^0
// Returns a vector representing this polynomial truncated to degree D_MAX.
Polynomial make_const(long long c) {
    // Initialize polynomial vector of size D_MAX + 1 with all zeros.
    Polynomial p(D_MAX + 1, 0); 
    // Set the coefficient for x^0 (constant term) if D_MAX >= 0.
    if (0 <= D_MAX) { 
       p[0] = c;
    }
    return p;
}

// Creates a polynomial representing the variable x.
// P(x) = 1 * x^1
// Returns a vector representing this polynomial truncated to degree D_MAX.
Polynomial make_x() {
    // Initialize polynomial vector of size D_MAX + 1 with all zeros.
    Polynomial p(D_MAX + 1, 0); 
    // Set the coefficient for x^1 if D_MAX >= 1.
    if (1 <= D_MAX) { 
        p[1] = 1;
    }
    // If D_MAX is 0, the polynomial x is represented as [0] effectively, since we only care about coefficient A_0.
    return p;
}

// Adds two polynomials p1 and p2.
// Returns the resulting polynomial truncated to degree D_MAX.
// Result coefficient A_i = p1[i] + p2[i]
Polynomial add(const Polynomial& p1, const Polynomial& p2) {
    // Initialize result polynomial vector of size D_MAX + 1 with zeros.
    Polynomial result(D_MAX + 1, 0); 
    // Perform element-wise addition for coefficients up to degree D_MAX.
    for (int i = 0; i <= D_MAX; ++i) {
        result[i] = p1[i] + p2[i]; 
    }
    return result;
}

// Multiplies two polynomials p1 and p2.
// Returns the resulting polynomial truncated to degree D_MAX.
// Result coefficient C_k = sum(p1[i] * p2[j]) for all i+j=k.
// Only terms with degree i+j <= D_MAX are considered.
Polynomial multiply(const Polynomial& p1, const Polynomial& p2) {
    // Initialize result polynomial vector of size D_MAX + 1 with zeros.
    Polynomial result(D_MAX + 1, 0); 
    // Iterate through coefficients of p1
    for (int i = 0; i <= D_MAX; ++i) {
        // Optimization: If coefficient p1[i] is 0, terms p1[i]*p2[j]*x^(i+j) are all 0. Skip inner loop.
        if (p1[i] == 0) continue; 
        // Iterate through coefficients of p2
        for (int j = 0; j <= D_MAX; ++j) {
            // Check if the resulting term's degree (i+j) is within the limit D_MAX.
            if (i + j <= D_MAX) { 
                // Add the product p1[i] * p2[j] to the coefficient of x^(i+j).
                // Potential overflow check could be added here if coefficients could exceed long long max,
                // but analysis suggests long long is sufficient for given constraints.
                result[i + j] += p1[i] * p2[j]; 
            }
            // Terms with resulting degree > D_MAX are implicitly ignored.
        }
    }
    return result;
}

// Computes the derivative of polynomial p.
// Returns the resulting polynomial truncated to degree D_MAX.
// If P(x) = sum(A_i * x^i), then P'(x) = sum(A_i * i * x^(i-1)).
// The new coefficient A'_j for x^j is derived from the original coefficient A_{j+1} of x^{j+1}.
// A'_j = A_{j+1} * (j+1).
Polynomial differentiate(const Polynomial& p) {
    // Initialize result polynomial vector of size D_MAX + 1 with zeros.
    Polynomial result(D_MAX + 1, 0); 
    // Iterate from i=1 because the constant term A_0 disappears upon differentiation.
    for (int i = 1; i <= D_MAX; ++i) {
        // The term A_i * x^i becomes A_i * i * x^(i-1).
        // This contributes to the coefficient of x^(i-1) in the derivative polynomial.
        // Cast i to long long during multiplication to prevent potential integer overflow if p[i] is large.
        result[i - 1] = p[i] * (long long)i; 
    }
    // The coefficient for x^D_MAX in the result will be 0, because it would come from differentiating a term with x^(D_MAX+1),
    // which is beyond the maximum degree D_MAX stored in p. This is handled by initialization to zeros.
    return result;
}

// Global parser state: current position index in the expression string S.
// Used by recursive parser functions to track progress through the string.
int pos;
// Global expression string. Storing globally avoids passing copies in recursion.
string S;

// Forward declarations for recursive descent parser functions.
// These functions implement the grammar rules and operator precedence.
Polynomial parse_expression_global(); // Handles '+' operations
Polynomial parse_term_global();       // Handles '*' operations
Polynomial parse_factor_global();     // Handles base units: constants, 'x', 'd{...}'

// Parses an expression according to the grammar: Expression ::= Term { '+' Term }
// Expressions are sums of terms. Addition has lower precedence.
Polynomial parse_expression_global() {
    // An expression starts with a term.
    Polynomial result = parse_term_global();
    // Check for subsequent terms connected by '+'.
    while (pos < S.length() && S[pos] == '+') {
        pos++; // Consume the '+' operator
        Polynomial next_term = parse_term_global(); // Parse the term following '+'
        result = add(result, next_term); // Add the parsed term to the running total
    }
    // Return the final polynomial representing the evaluated expression.
    return result; 
}

// Parses a term according to the grammar: Term ::= Factor { '*' Factor }
// Terms are products of factors. Multiplication has higher precedence than addition.
Polynomial parse_term_global() {
    // A term starts with a factor.
    Polynomial result = parse_factor_global();
    // Check for subsequent factors connected by '*'.
    while (pos < S.length() && S[pos] == '*') {
        pos++; // Consume the '*' operator
        Polynomial next_factor = parse_factor_global(); // Parse the factor following '*'
        result = multiply(result, next_factor); // Multiply the running result by the parsed factor
    }
    // Return the final polynomial representing the evaluated term.
    return result; 
}

// Parses a factor according to the grammar: Factor ::= Constant | VariableX | 'd{' Expression '}'
// Factors are the basic building blocks of the expression.
Polynomial parse_factor_global() {
    // Basic check for boundary conditions or end of relevant context (like finding '}')
    if (pos >= S.length() || S[pos] == '}') {
        // If '}' is encountered, it signifies the end of a 'd{...}' block, which should be handled by the calling context.
        // Returning zero polynomial can signal this, or simply rely on caller to check pos.
        // If end of string is reached unexpectedly, it implies malformed input.
        // Under problem constraints (valid input), this case might signal expected end (like closing brace).
        return Polynomial(D_MAX + 1, 0); // Return zero polynomial as a safe default/fallback.
    }

    // Identify the type of factor based on the character at the current position 'pos'.
    if (isdigit(S[pos])) {
        // Factor is a constant (guaranteed to be single digit 1-9 by problem statement).
        long long val = S[pos] - '0'; // Convert character digit to integer value.
        pos++; // Advance parser position past the digit.
        return make_const(val); // Return the polynomial representation of the constant.
    } else if (S[pos] == 'x') {
        // Factor is the variable 'x'.
        pos++; // Advance parser position past 'x'.
        return make_x(); // Return the polynomial representation of 'x'.
    } else if (S[pos] == 'd') {
        // Factor is a differentiation operation 'd{...}'.
        pos++; // Consume 'd'.
        // Check for opening brace '{' which must follow 'd'.
        if (pos >= S.length() || S[pos] != '{') {
             // Error condition: Input format violation (should not happen with valid input).
             return Polynomial(D_MAX+1, 0);
        }
        pos++; // Consume '{'.
        
        // Recursively call parse_expression_global() to parse the expression inside the braces.
        // This recursive call will consume characters until it hits the matching closing brace '}'.
        Polynomial expr_poly = parse_expression_global(); 
        
        // After the recursive call returns, 'pos' should be pointing at the matching '}'.
        // Check for the closing brace '}' to confirm correct structure.
        if (pos >= S.length() || S[pos] != '}') {
             // Error condition: Input format violation (mismatched braces or structure error).
             return Polynomial(D_MAX+1, 0);
        }
        pos++; // Consume '}'.
        
        // Compute and return the derivative of the parsed inner expression polynomial.
        return differentiate(expr_poly);

    } else {
         // If the character at S[pos] doesn't match any expected factor type, it indicates an error
         // or an unexpected situation (e.g., encountering '}' incorrectly).
         // Return zero polynomial for robustness. Valid inputs shouldn't reach here improperly.
         return Polynomial(D_MAX + 1, 0); 
    }
}


int main() {
    // Optimize C++ standard input/output streams for performance.
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int N; // Length of the expression string S (provided but not directly used in parsing logic).
    cin >> N >> D_MAX >> S; // Read N, maximum degree d, and the expression string S.

    pos = 0; // Initialize the global parser position to the start of the string S.
    // Call the top-level parser function parse_expression_global() to evaluate the entire expression.
    Polynomial final_poly = parse_expression_global();

    // Output the resulting polynomial coefficients A_0, A_1, ..., A_D_MAX.
    for (int i = 0; i <= D_MAX; ++i) {
        cout << final_poly[i] << (i == D_MAX ? "" : " "); // Print each coefficient followed by a space, except for the last one.
    }
    cout << endl; // Print a newline character at the end of the output.

    return 0; // Indicate successful program execution.
}
0