Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用C+的通用段树实现+;模板_C++_Templates_Inheritance_Functor_Segment Tree - Fatal编程技术网

C++ 使用C+的通用段树实现+;模板

C++ 使用C+的通用段树实现+;模板,c++,templates,inheritance,functor,segment-tree,C++,Templates,Inheritance,Functor,Segment Tree,我试图为更新和范围查询创建一个通用的段树类 我希望用户提供元素的类型T和一个函数,我将其命名为compose,而不是假设元素只是整数,对一系列元素执行的操作是它们的和或积 此函数接受两个类型为T的参数,并返回一个类型为T的值。此返回值是在2个元素范围内执行所需操作时的结果,我可以使用该操作在任意数量的元素范围内执行相同操作 课程安排如下: #include <functional> template<class T> class SegmentTree { p

我试图为更新和范围查询创建一个通用的段树类

我希望用户提供元素的类型T和一个函数,我将其命名为compose,而不是假设元素只是整数,对一系列元素执行的操作是它们的和或积

此函数接受两个类型为T的参数,并返回一个类型为T的值。此返回值是在2个元素范围内执行所需操作时的结果,我可以使用该操作在任意数量的元素范围内执行相同操作

课程安排如下:

#include <functional>

template<class T>
class SegmentTree {

    public:
        class binary_function_unitype: public std::binary_function<T,T,T> {
            public:
                virtual T operator() (T arg1, T arg2) {};
        };

    private:
        class Node {
            public:
                T value;
                int seg_start, seg_end;
                Node* left;
                Node* right;
                Node (T value, int seg_start, int seg_end, Node* left=0, Node* right=0) {
                    this->value = value;
                    this->seg_start = seg_start;
                    this->seg_end = seg_end;
                    this->left = left;
                    this->right = right;
                }
        };

        // Not expecting the compose function to be robust enough.
        T composeUtil (T arg1, T arg2) {
            if (arg1!=0 && arg2!=0)
                return compose(arg1,arg2);
            else if (arg1!=0)
                return arg1;
            else if (arg2!=0)
                return arg2;
        }

        // Creating the Segment Tree.
        Node* createTree (T leaves[], int start, int end) {
            // base case - leaf of tree.
            if (start==end)
                return new Node(leaves[start],start,start,0,0);
            // general case.
            int mid = start + (end-start)/2;
            Node* left = createTree(leaves,start,mid);
            Node* right = createTree(leaves,mid+1,end);
            T retValue = composeUtil(left->value,right->value);
            return new Node(retValue,start,end,left,right);
        }

        // Range Query helper.
        T queryUtil (Node* root, int start, int end) {
            int seg_start = root->seg_start, seg_end = root->seg_end;
            if (seg_start>end || seg_end<start)
                return 0;
            else if (seg_start>=start && seg_end<=end)
                return root->value;
            else
                return compose( queryUtil(root->left,start,end), queryUtil(root->right,start,end));
        }

        // Helper function for Updating the Segment Tree.
        void updateUtil (Node* root, int position, T updatedValue) {
            int seg_start = root->seg_start, seg_end = root->seg_end;
            if(seg_start>position || seg_end<position)
                return;
            else if(seg_start==seg_end)
                root->value = updatedValue;
            else
                root->value = composeUtil(root->left->value,root->right->value);
        }

        // Freeing the memory allocated to the Segment Tree.
        void destroyTree(Node* root) {
            if (root->left!=0)
                destroyTree(root->left);
            if (root->right!=0)
                destroyTree(root->right);
            delete root;
        }

        Node* root;
        binary_function_unitype compose;

    public:
        SegmentTree (T leaves[], binary_function_unitype compose, int start, int end) {
            this->compose = compose;
            this->root = createTree(leaves, start, end);
        }

        T query (int start, int end) {
            return queryUtil(root, start, end);
        }

        void update (int position, T updatedValue) {
            updateUtil(root, position, updatedValue);
        }

        ~SegmentTree () {
            destroyTree(root);
        }
};
#include <iostream>
#include "SegmentTree.h"

using namespace std;

class Compose: public SegmentTree<int>::binary_function_unitype {
    public:
        int operator() (int arg1, int arg2) {
            return arg1+arg2;
        }
};

int main()
{
    int num;
    cin>>num;
    int arr[num];
    for(int i=0;i<num;i++)
        cin>>arr[i];
    Compose compose;
    SegmentTree<int> segTree(arr, compose, 0, num-1);
    int s,e;
    cin>>s>>e;
    cout<<segTree.query(s-1,e-1);
    return 0;
}
#包括
模板
类分段树{
公众:
类二进制函数单元类型:公共std::二进制函数{
公众:
虚拟T运算符()(T arg1,T arg2){};
};
私人:
类节点{
公众:
T值;
int seg_开始,seg_结束;
节点*左;
节点*右;
节点(T值,整数段开始,整数段结束,节点*左=0,节点*右=0){
这个->值=值;
此->分段启动=分段启动;
此->分段结束=分段结束;
这个->左=左;
这个->右=右;
}
};
//不希望compose函数足够健壮。
T复合物(T arg1,T arg2){
如果(arg1!=0&&arg2!=0)
返回组合(arg1、arg2);
否则如果(arg1!=0)
返回arg1;
否则如果(arg2!=0)
返回arg2;
}
//创建段树。
节点*createTree(T叶[],int开始,int结束){
//基本情况-树的叶子。
如果(开始==结束)
返回新节点(离开[start],开始,开始,0,0);
//一般情况。
int mid=开始+(结束-开始)/2;
Node*left=createTree(叶子、开始、中间);
Node*right=createTree(叶子,中间+1,结束);
T retValue=composeUtil(左->值,右->值);
返回新节点(retValue、start、end、left、right);
}
//范围查询帮助程序。
T queryUtil(节点*根,int开始,int结束){
int seg_start=root->seg_start,seg_end=root->seg_end;
如果(seg_start>end | | seg_end=start&&seg_endvalue;
其他的
返回组合(queryUtil(root->left,start,end),queryUtil(root->right,start,end));
}
//用于更新段树的辅助函数。
void updateUtil(节点*根,int位置,T updatedValue){
int seg_start=root->seg_start,seg_end=root->seg_end;
如果(seg_开始>位置| | seg_结束值=更新值;
其他的
根->值=composeUtil(根->左->值,根->右->值);
}
//释放分配给段树的内存。
无效目录树(节点*根){
如果(根->左!=0)
破坏树(根->左);
如果(根->右!=0)
破坏树(根->右);
删除根;
}
节点*根;
二进制函数单元类型组合;
公众:
分段树(T叶[],二进制函数\单元类型组合,整数开始,整数结束){
这个->组合=组合;
此->根=创建树(叶子、开始、结束);
}
T查询(整数开始,整数结束){
返回queryUtil(根、开始、结束);
}
无效更新(int位置,T updatedValue){
updateUtil(根、位置、updatedValue);
}
~z~树(){
树(根);
}
};
当我尝试使用这个类时,结果是没有使用作为参数的compose函数,相反,使用的是类二进制函数的unitype

我希望用户的函数定义会覆盖类binary\u function\u unitype中的函数定义,我的工作也会完成。但这并没有发生。使用该类的程序如下所示:

#include <functional>

template<class T>
class SegmentTree {

    public:
        class binary_function_unitype: public std::binary_function<T,T,T> {
            public:
                virtual T operator() (T arg1, T arg2) {};
        };

    private:
        class Node {
            public:
                T value;
                int seg_start, seg_end;
                Node* left;
                Node* right;
                Node (T value, int seg_start, int seg_end, Node* left=0, Node* right=0) {
                    this->value = value;
                    this->seg_start = seg_start;
                    this->seg_end = seg_end;
                    this->left = left;
                    this->right = right;
                }
        };

        // Not expecting the compose function to be robust enough.
        T composeUtil (T arg1, T arg2) {
            if (arg1!=0 && arg2!=0)
                return compose(arg1,arg2);
            else if (arg1!=0)
                return arg1;
            else if (arg2!=0)
                return arg2;
        }

        // Creating the Segment Tree.
        Node* createTree (T leaves[], int start, int end) {
            // base case - leaf of tree.
            if (start==end)
                return new Node(leaves[start],start,start,0,0);
            // general case.
            int mid = start + (end-start)/2;
            Node* left = createTree(leaves,start,mid);
            Node* right = createTree(leaves,mid+1,end);
            T retValue = composeUtil(left->value,right->value);
            return new Node(retValue,start,end,left,right);
        }

        // Range Query helper.
        T queryUtil (Node* root, int start, int end) {
            int seg_start = root->seg_start, seg_end = root->seg_end;
            if (seg_start>end || seg_end<start)
                return 0;
            else if (seg_start>=start && seg_end<=end)
                return root->value;
            else
                return compose( queryUtil(root->left,start,end), queryUtil(root->right,start,end));
        }

        // Helper function for Updating the Segment Tree.
        void updateUtil (Node* root, int position, T updatedValue) {
            int seg_start = root->seg_start, seg_end = root->seg_end;
            if(seg_start>position || seg_end<position)
                return;
            else if(seg_start==seg_end)
                root->value = updatedValue;
            else
                root->value = composeUtil(root->left->value,root->right->value);
        }

        // Freeing the memory allocated to the Segment Tree.
        void destroyTree(Node* root) {
            if (root->left!=0)
                destroyTree(root->left);
            if (root->right!=0)
                destroyTree(root->right);
            delete root;
        }

        Node* root;
        binary_function_unitype compose;

    public:
        SegmentTree (T leaves[], binary_function_unitype compose, int start, int end) {
            this->compose = compose;
            this->root = createTree(leaves, start, end);
        }

        T query (int start, int end) {
            return queryUtil(root, start, end);
        }

        void update (int position, T updatedValue) {
            updateUtil(root, position, updatedValue);
        }

        ~SegmentTree () {
            destroyTree(root);
        }
};
#include <iostream>
#include "SegmentTree.h"

using namespace std;

class Compose: public SegmentTree<int>::binary_function_unitype {
    public:
        int operator() (int arg1, int arg2) {
            return arg1+arg2;
        }
};

int main()
{
    int num;
    cin>>num;
    int arr[num];
    for(int i=0;i<num;i++)
        cin>>arr[i];
    Compose compose;
    SegmentTree<int> segTree(arr, compose, 0, num-1);
    int s,e;
    cin>>s>>e;
    cout<<segTree.query(s-1,e-1);
    return 0;
}
#包括
#包括“SegmentTree.h”
使用名称空间std;
类组合:公共分段树::二进制函数单元类型{
公众:
int运算符()(int arg1,int arg2){
返回arg1+arg2;
}
};
int main()
{
int-num;
cin>>num;
int-arr[num];
对于(int i=0;i>arr[i];
作曲;
分段树segTree(arr,compose,0,num-1);
int s,e;
cin>>s>>e;

cout构造函数按值获取一个
二进制函数\u unitype
,因此它将