C++ 段树中的查询

C++ 段树中的查询,c++,algorithm,data-structures,tree,segment-tree,C++,Algorithm,Data Structures,Tree,Segment Tree,我一直在努力理解query()函数中最后6行的逻辑 这是spoj上问题的代码 解决方案 #包括 #包括 #定义最大70000 使用名称空间std; 结构号{ int lsum、rsum、msum; }; 整数数组[MAX+1],和[MAX+1]; 没有树[4*MAX+1]; void init(int节点,int i,int j){ 如果(i==j){ 树[节点]=((否){array[i],array[i],array[i]}); } 否则{ init(节点*2,i,(i+j)/2); 初始(

我一直在努力理解
query()
函数中最后6行的逻辑

这是spoj上问题的代码

解决方案

#包括
#包括
#定义最大70000
使用名称空间std;
结构号{
int lsum、rsum、msum;
};
整数数组[MAX+1],和[MAX+1];
没有树[4*MAX+1];
void init(int节点,int i,int j){
如果(i==j){
树[节点]=((否){array[i],array[i],array[i]});
}
否则{
init(节点*2,i,(i+j)/2);
初始(节点*2+1,(i+j)/2+1,j);
无左=树[节点*2],右=树[节点*2+1];
树[node].lsum=max(left.lsum,sums[(i+j)/2]-sums[i-1]+right.lsum);
树[node].rsum=max(right.rsum,sums[j]-sums[(i+j)/2]+left.rsum);
树[node].msum=max(left.msum,max(right.msum,left.rsum+right.lsum));
}}
无查询(int节点、int a、int b、int i、int j){
如果(a==i&&b==j){
返回树[节点];
}
如果(j(a+b)/2){
返回查询(节点*2+1,(a+b)/2+1,b,i,j);
}
无左=查询(节点*2,a,(a+b)/2,i,(a+b)/2);
无权限=查询(节点*2+1,(a+b)/2+1,b,(a+b)/2+1,j);
返回((否){
最大值(left.lsum,总和[(a+b)/2]-总和[i-1]+right.lsum),
max(right.rsum,sums[b]-sums[(a+b)/2]+left.rsum),
最大值(left.msum,max(right.msum,left.rsum+right.lsum))
} ); }
int main(){
int i,N,q,l,r;
scanf(“%d”和“&N”);
对于(i=0;i
查询函数中no=left&&no=right和return的需要是什么

是否有人建议更好的实施/教程fr段树

我无法在实现数据结构时可视化这些递归。有小费吗

这个no=left&&no=right和返回的需要是什么 查询函数

在这种情况下,您要查询的段同时进入两个子段


假设您有一个覆盖区间1..n且有2个子节点1。。n/2和n/2+1..n。如果您想查询某个间隔[a,b],以便a,这会有所帮助!。但是,如何善于实现数据结构呢?在某些问题上,我们需要稍微调整一下实现。如何实现这种状态?我很想知道这一点。您需要实现和调试数据结构的问题。几次之后,你应该能够知道什么是棘手的部分以及如何管理它们。当您开始使用一个新的结构时,请确保您有足够的调试信息可以查看,并且您对它应该如何在纸上工作有很好的理解。对不起,这里没有魔弹。
#include <cstdio>
#include <algorithm>
#define MAX 70000

using namespace std;

struct no {
int lsum, rsum, msum;
};

int array[ MAX + 1 ], sums[ MAX + 1 ];
no tree[ 4 * MAX + 1 ];

 void init( int node, int i, int j ) {
if ( i == j ) {
    tree[ node ] = ( ( no ) { array[ i ], array[ i ], array[ i ] } );
}
else {
    init( node * 2, i, ( i + j ) / 2 );
    init( node * 2 + 1, ( i + j ) / 2 + 1, j );
    no left = tree[ node * 2 ], right = tree[ node * 2 + 1 ];
    tree[ node ].lsum = max( left.lsum, sums[ ( i + j ) / 2 ] - sums[ i - 1 ] + right.lsum );
    tree[ node ].rsum = max( right.rsum, sums[ j ] - sums[ ( i + j ) / 2 ] + left.rsum );
    tree[ node ].msum = max( left.msum, max( right.msum, left.rsum + right.lsum ) );
}}

 no query( int node, int a, int b, int i, int j ) {
if ( a == i && b == j ) {
    return tree[ node ];
}
else if ( j <= ( a + b ) / 2 ) {
    return query( node * 2, a, ( a + b ) / 2, i, j );
}
if ( i > ( a + b ) / 2 ) {
    return query( node * 2 + 1, ( a + b ) / 2 + 1, b, i, j );
}
no left = query( node * 2, a, ( a + b ) / 2, i, ( a + b ) / 2 );
no right = query( node * 2 + 1, ( a + b ) / 2 + 1, b, ( a + b ) / 2 + 1, j );
return ( ( no ) {
            max( left.lsum, sums[ ( a + b ) / 2 ] - sums[ i - 1 ] + right.lsum ),
            max( right.rsum, sums[ b ] - sums[ ( a + b ) / 2 ] + left.rsum ),
            max( left.msum, max( right.msum, left.rsum + right.lsum ) )
            } ); }

int main() {
int i, N, q, l, r;
scanf( "%d", &N );
for ( i = 0; i < N; ++i ) {
    scanf( "%d", array + i );
    if ( i == 0 ) {
        sums[ i ] = array[ i ];
    }
    else {
        sums[ i ] = sums[ i - 1 ] + array[ i ];
    }
}
init( 1, 0, N - 1 );
scanf( "%d", &q );
for ( i = 0; i < q; ++i ) {
    scanf( "%d%d", &l, &r );
    --l;
    --r;
    printf( "%d\n", query( 1, 0, N - 1, l, r ).msum );
}
return 0; }