Блог пользователя aajjbb

Автор aajjbb, 14 лет назад, По-английски

Hello, I'm a pretty beginner with segment trees and I'm in doubt on this problem, I can build the tree but the queries for look for the right interval with the biggest sum is wrong, can someone point out what is wrong with my method func. Thanks in advance.

Problem Statement

#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <utility>
#include <functional>
#include <valarray>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <climits>

using namespace std;

#define REP(i, n) for(i = 0; i < (n); i++)
#define FOR(i, a, n) for(i = a; i < n; i++)
#define REV(i, a, n) for(i = a; i > n; i--)

template<typename T> T gcd(T a, T b) {
    if(!b) return a;
    return gcd(b, a % b);
}
template<typename T> T lcm(T a, T b) {
    return a * b / gcd(a, b);
}

typedef long long ll;
typedef long double ld;

#define MAXN 5000010
#define INF 1000001000

int n, a[MAXN], t[4*MAXN];
int b, c, i, m, tmp, x;

void build (int a[], int v, int tl, int tr) {
    if (tl == tr)
        t[v] = a[tl];
    else {
        int tm = (tl + tr) / 2;
        build (a, v*2, tl, tm);
        build (a, v*2+1, tm+1, tr);
        t[v] = t[v*2] + t[v*2+1];
    }
}

int func(int v, int tl, int tr, int l, int r) {
    if(l > tr || r < tl) {
        return -INF;
    }
    if(tl >= l && tr <= r) {
        return t[v];
    }
    int tm = (tl + tr) / 2;
    int p1 = func(2 * v, tl, (tl + tr) / 2, l, r);
    int p2 = func(2 * v + 1, ((tl + tr) / 2) + 1, tr, l, r);

    if(p1 > p2) return p1;
    else return p2;
}
int main(void) {
    freopen("i.in", "r", stdin);
    scanf("%d", &x);
    REP(i, x) {
        scanf("%d", &a[i+1]);
    }
    build(a, 1, 1, x+1);    
    scanf("%d", &m);
    REP(i, m) {
        scanf("%d%d", &b, &c);
        printf("%d\n", func(1, 1, x+1, b, c));
    }
    return 0;
}


  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

»
14 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

As I understand, in func you are returning p1 or p2, but result may be the intersection of them.
Hint in spoiler.

»
14 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

For each segment [x..y] you need to know four integers:
1) SUM — sum of all numbers in this segment
2) BEST — maximal sum of any subsegment of this segment
3) BestLeft maximal sum of any subsegment [i..j] of this segment, and i == x
4) BestRight maximal sum of any subsegment [i..j] of this segment, and j == y
if we know all these integers for two intervals [L..M] and [M+1..R] we can easy calculate them for interval [L..R].

»
14 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

here you can get a nice tutorial about maximum sub-segment sum. http://e-maxx.ru/algo/segment_tree

»
14 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

if all numbers r negative ur program will print negative number,not sure but maybe u can take an empty segment so the answer will be 0.