Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

โปรแกรมหาผลรวมอาร์เรย์ arr[i] = i × (-1)^i ในช่วง L ถึง R C++

ภาพรวมปัญหา

กำหนดอาร์เรย์ที่ arr[i] = i × (-1)ⁱ (1-indexed) ต้องการหาผลรวมในช่วงดัชนี L ถึง R

ลำดับ: -1, 2, -3, 4, -5, 6, -7, 8, ...

  • Index คี่: ค่าลบ (-i)
  • Index คู่: ค่าบวก (+i)

ตัวอย่าง

L=2, R=6
arr[2]=2, arr[3]=-3, arr[4]=4, arr[5]=-5, arr[6]=6
Sum = 2 + (-3) + 4 + (-5) + 6 = 4

วิธีที่ 1: Brute Force O(R-L+1)

long long sumBruteForce(int L, int R) {
    long long sum = 0;
    for (int i = L; i <= R; i++) {
        if (i % 2 == 0) sum += i;      // Even: +i
        else sum -= i;                  // Odd: -i
    }
    return sum;
}

วิธีที่ 2: สูตรคณิตศาสตร์ O(1)

แยกผลรวมเป็น: (ผลรวมเลขคู่) - (ผลรวมเลขคี่)

ผลรวมเลขคู่จาก 1 ถึง n:

Even Sum = 2 + 4 + ... + 2k = 2(1+2+...+k) = k(k+1)
โดย k = floor(n/2)

ผลรวมเลขคี่จาก 1 ถึง n:

Odd Sum = 1 + 3 + ... + (2k-1) = k²
โดย k = ceil(n/2) = (n+1)/2

ผลรวมในช่วง [L, R]:

Sum(L,R) = [EvenSum(R) - EvenSum(L-1)] - [OddSum(R) - OddSum(L-1)]

ตัวอย่างโค้ด C++ สมบูรณ์

#include <iostream>
using namespace std;

long long evenSum(long long n) {
    // ผลรวมเลขคู่ 2+4+...+2k โดย k = n/2
    long long k = n / 2;
    return k * (k + 1);
}

long long oddSum(long long n) {
    // ผลรวมเลขคี่ 1+3+...+(2k-1) โดย k = (n+1)/2
    long long k = (n + 1) / 2;
    return k * k;
}

long long rangeSumFormula(int L, int R) {
    long long evenR = evenSum(R);
    long long evenL = evenSum(L - 1);
    long long oddR = oddSum(R);
    long long oddL = oddSum(L - 1);
    
    return (evenR - evenL) - (oddR - oddL);
}

long long rangeSumBruteForce(int L, int R) {
    long long sum = 0;
    for (int i = L; i <= R; i++) {
        if (i % 2 == 0) sum += i;
        else sum -= i;
    }
    return sum;
}

void testCase(int L, int R) {
    cout << "L=" << L << ", R=" << R << endl;
    cout << "  Brute Force: " << rangeSumBruteForce(L, R) << endl;
    cout << "  Formula:     " << rangeSumFormula(L, R) << endl;
    
    // แสดงรายการ
    cout << "  Terms: ";
    for (int i = L; i <= R; i++) {
        int val = (i % 2 == 0) ? i : -i;
        cout << val << " ";
    }
    cout << endl << endl;
}

int main() {
    cout << "=== Sum of arr[i] = i*(-1)^i from L to R ===\n\n";
    
    testCase(2, 6);     // 2-3+4-5+6 = 4
    testCase(3, 15);    // -3+4-5+6-7+8-9+10-11+12-13+14-15 = -9
    testCase(1, 10);    // -1+2-3+4-5+6-7+8-9+10 = 5
    testCase(1, 100);   // Large test
    testCase(1000000, 2000000);  // Very large test (Formula only)
    
    return 0;
}

ผลลัพธ์ตัวอย่าง

=== Sum of arr[i] = i*(-1)^i from L to R ===

L=2, R=6
  Brute Force: 4
  Formula:     4
  Terms: 2 -3 4 -5 6 

L=3, R=15
  Brute Force: -9
  Formula:     -9
  Terms: -3 4 -5 6 -7 8 -9 10 -11 12 -13 14 -15 

L=1, 10
  Brute Force: 5
  Formula:     5
  Terms: -1 2 -3 4 -5 6 -7 8 -9 10 

L=1, 100
  Brute Force: 50
  Formula:     50
  Terms: (many)...

L=1000000, 2000000
  Brute Force: (slow)
  Formula:     500000500000

การตรวจสอบสูตร (Verification)

nEven SumOdd SumTotal (1 to n)
101-1
2211
324-2
4642
569-3
61293
1030255
1002550250050

รูปแบบที่สังเกตได้ (Pattern)

Sum(1 to n) = 
  n/2        if n is even
  -(n+1)/2   if n is odd

Sum(L to R) = Sum(1 to R) - Sum(1 to L-1)

โค้ดเวอร์ชันลดรูป (Simplified Formula)

long long prefixSum(long long n) {
    if (n % 2 == 0) return n / 2;
    return -(n + 1) / 2;
}

long long rangeSumSimple(int L, int R) {
    return prefixSum(R) - prefixSum(L - 1);
}

ความซับซ้อนเปรียบเทียบ

MethodTimeSpaceMax N
Brute ForceO(R-L)O(1)~10⁷
Even/Odd FormulaO(1)O(1)10¹⁸
Simplified PrefixO(1)O(1)10¹⁸

ประยุกต์ใช้

  • การคำนวณซีรีส์สลับเครื่องหมาย (Alternating Series)
  • Digital Signal Processing
  • Mathematical Programming Contests
  • การพิสูจน์ทางคณิตศาสตร์ (Mathematical Induction)