public TMonoid Query(int left, int right)
        {
            if (left < 0 || right < left || Length < right)
            {
                throw new ArgumentOutOfRangeException();
            }
            var(sml, smr) = (_oracle.MonoidIdentity, _oracle.MonoidIdentity);
            left         += _dataSize;
            right        += _dataSize;
            while (left < right)
            {
                if ((left & 1) == 1)
                {
                    sml = _oracle.Operate(sml, _data[left++]);
                }
                if ((right & 1) == 1)
                {
                    smr = _oracle.Operate(_data[--right], smr);
                }
                left  >>= 1;
                right >>= 1;
            }

            return(_oracle.Operate(sml, smr));
        }
            public TMonoid Query(int l, int r)
            {
                var sum = _id;

                for (var i = l; i < r; i++)
                {
                    sum = _oracle.Operate(sum, _data[i]);
                }
                return(sum);
            }