Submission #1327640

#TimeUsernameProblemLanguageResultExecution timeMemory
1327640profalaxizSpiral (BOI16_spiral)C++20
100 / 100
0 ms332 KiB
#include <iostream>
#include <algorithm>

using namespace std;

const long long MOD = 1e9 + 7;
const long long INV2 = 500000004;
const long long INV6 = 166666668;

long long safe_mod(long long x) {
    x %= MOD;
    if (x < 0) x += MOD;
    return x;
}

// Power sum formulas modulo 1e9+7
long long S0(long long N) {
    if (N < 0) return 0;
    return safe_mod(N + 1);
}
long long S1(long long N) {
    if (N < 0) return 0;
    long long res = safe_mod(N) * safe_mod(N + 1) % MOD;
    return res * INV2 % MOD;
}
long long S2(long long N) {
    if (N < 0) return 0;
    long long res = safe_mod(N) * safe_mod(N + 1) % MOD;
    res = res * safe_mod(2 * N + 1) % MOD;
    return res * INV6 % MOD;
}
long long S3(long long N) {
    if (N < 0) return 0;
    long long res = S1(N);
    return res * res % MOD;
}

// Computes sum of C1*a^2 + C2*a + C3*b + C4 for a in [0, A], b in [0, min(a, B)]
long long sum_term1(long long A, long long B, long long C1, long long C2, long long C3, long long C4) {
    if (A < 0 || B < 0) return 0;
    C1 = safe_mod(C1); C2 = safe_mod(C2); C3 = safe_mod(C3); C4 = safe_mod(C4);
    long long M = min(A, B);
    long long ans = 0;

    long long alpha = C1;
    long long beta = safe_mod(C1 + C2 + C3 * INV2);
    long long gamma = safe_mod(C2 + C4 + C3 * INV2);
    long long delta = C4;

    ans = safe_mod(ans + alpha * S3(M));
    ans = safe_mod(ans + beta * S2(M));
    ans = safe_mod(ans + gamma * S1(M));
    ans = safe_mod(ans + delta * S0(M));

    if (A > B) {
        long long K2 = safe_mod(C1 * safe_mod(B + 1));
        long long K1 = safe_mod(C2 * safe_mod(B + 1));
        long long K0 = safe_mod(C4 * safe_mod(B + 1) + C3 * S1(B));

        long long sum2 = safe_mod(S2(A) - S2(B));
        long long sum1 = safe_mod(S1(A) - S1(B));
        long long sum0 = safe_mod(S0(A) - S0(B));

        ans = safe_mod(ans + K2 * sum2);
        ans = safe_mod(ans + K1 * sum1);
        ans = safe_mod(ans + K0 * sum0);
    }
    return ans;
}

// Computes sum of C1*b^2 + C2*b + C3*a + C4 for b in [1, B], a in [0, min(b-1, A)]
long long sum_term2(long long B, long long A, long long C1, long long C2, long long C3, long long C4) {
    if (B < 1 || A < 0) return 0;
    C1 = safe_mod(C1); C2 = safe_mod(C2); C3 = safe_mod(C3); C4 = safe_mod(C4);
    long long M_lim = min(B, A + 1);
    long long ans = 0;

    if (M_lim >= 1) {
        long long alpha = C1;
        long long beta = safe_mod(C2 + C3 * INV2);
        long long gamma = safe_mod(C4 - C3 * INV2);

        ans = safe_mod(ans + alpha * S3(M_lim));
        ans = safe_mod(ans + beta * S2(M_lim));
        ans = safe_mod(ans + gamma * S1(M_lim));
    }

    if (B > A + 1) {
        long long K2 = safe_mod(C1 * safe_mod(A + 1));
        long long K1 = safe_mod(C2 * safe_mod(A + 1));
        long long K0 = safe_mod(C4 * safe_mod(A + 1) + C3 * S1(A));

        long long sum2 = safe_mod(S2(B) - S2(M_lim));
        long long sum1 = safe_mod(S1(B) - S1(M_lim));
        long long sum0 = safe_mod(B - M_lim);

        ans = safe_mod(ans + K2 * sum2);
        ans = safe_mod(ans + K1 * sum1);
        ans = safe_mod(ans + K0 * sum0);
    }
    return ans;
}

// 2D Prefix Sums mapped for each quadrant
long long pref_Q1(long long U, long long V) {
    if (U < 0 || V < 0) return 0;
    return safe_mod(sum_term1(U, V, 4, -3, 1, 1) + sum_term2(V, U, 4, -1, -1, 1));
}
long long pref_Q2(long long U, long long V) {
    if (U < 0 || V < 0) return 0;
    return safe_mod(sum_term1(U, V, 4, 1, -1, 1) + sum_term2(V, U, 4, -1, 1, 1));
}
long long pref_Q3(long long U, long long V) {
    if (U < 0 || V < 0) return 0;
    return safe_mod(sum_term1(U, V, 4, 1, 1, 1) + sum_term2(V, U, 4, 3, -1, 1));
}
long long pref_Q4(long long U, long long V) {
    if (U < 0 || V < 0) return 0;
    // Tiebreaker adjustments assigned mapped Bottom region as Term 1 correctly
    return safe_mod(sum_term1(V, U, 4, 3, 1, 1) + sum_term2(U, V, 4, -3, -1, 1));
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    long long n;
    int q;
    if (!(cin >> n >> q)) return 0;

    while (q--) {
        long long X1, Y1, X2, Y2;
        cin >> X1 >> Y1 >> X2 >> Y2;

        long long total_sum = 0;

        // Extract sum originating in Q1
        long long u1 = max(0LL, X1), u2 = X2, v1 = max(0LL, Y1), v2 = Y2;
        if (u1 <= u2 && v1 <= v2) {
            total_sum = safe_mod(total_sum + pref_Q1(u2, v2) - pref_Q1(u1 - 1, v2) - pref_Q1(u2, v1 - 1) + pref_Q1(u1 - 1, v1 - 1));
        }

        // Extract sum originating in Q2 (exclusive of Y axis overlap)
        long long x_s2 = X1, x_e2 = min(-1LL, X2), y_s2 = max(0LL, Y1), y_e2 = Y2;
        if (x_s2 <= x_e2 && y_s2 <= y_e2) {
            u1 = -x_e2; u2 = -x_s2; v1 = y_s2; v2 = y_e2;
            total_sum = safe_mod(total_sum + pref_Q2(u2, v2) - pref_Q2(u1 - 1, v2) - pref_Q2(u2, v1 - 1) + pref_Q2(u1 - 1, v1 - 1));
        }

        // Extract sum originating in Q3 (exclusive of X & Y axes overlaps)
        long long x_s3 = X1, x_e3 = min(-1LL, X2), y_s3 = Y1, y_e3 = min(-1LL, Y2);
        if (x_s3 <= x_e3 && y_s3 <= y_e3) {
            u1 = -x_e3; u2 = -x_s3; v1 = -y_e3; v2 = -y_s3;
            total_sum = safe_mod(total_sum + pref_Q3(u2, v2) - pref_Q3(u1 - 1, v2) - pref_Q3(u2, v1 - 1) + pref_Q3(u1 - 1, v1 - 1));
        }

        // Extract sum originating in Q4 (exclusive of X axis overlap)
        long long x_s4 = max(0LL, X1), x_e4 = X2, y_s4 = Y1, y_e4 = min(-1LL, Y2);
        if (x_s4 <= x_e4 && y_s4 <= y_e4) {
            u1 = x_s4; u2 = x_e4; v1 = -y_e4; v2 = -y_s4;
            total_sum = safe_mod(total_sum + pref_Q4(u2, v2) - pref_Q4(u1 - 1, v2) - pref_Q4(u2, v1 - 1) + pref_Q4(u1 - 1, v1 - 1));
        }

        cout << total_sum << "\n";
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...