Same approach as last time, O(logN) instantiation depth. Using only one overload, so it should consume less resources.
Warning: it currently removes references from the tuple types.
Note: Removed the reference from pack::declval. I think it still works in every case.
indices trick in O(log(N)) instantiations, by Xeo; modified to use std::size_t instead of unsigned
    #include <cstddef>
    // using aliases for cleaner syntax
    template<class T> using Invoke = typename T::type;
    template<std::size_t...> struct seq{ using type = seq; };
    template<class S1, class S2> struct concat;
    template<std::size_t... I1, std::size_t... I2>
    struct concat<seq<I1...>, seq<I2...>>
      : seq<I1..., (sizeof...(I1)+I2)...>{};
    template<class S1, class S2>
    using Concat = Invoke<concat<S1, S2>>;
    template<std::size_t N> struct gen_seq;
    template<std::size_t N> using GenSeq = Invoke<gen_seq<N>>;
    template<std::size_t N>
    struct gen_seq : Concat<GenSeq<N/2>, GenSeq<N - N/2>>{};
    template<> struct gen_seq<0> : seq<>{};
    template<> struct gen_seq<1> : seq<0>{};
Today, I realized there's a different, simpler and probably faster (compilation time) solution to get the nth type of a tuple (basically an implementation of std::tuple_element). Even though it's a direct solution of another question, I'll also post it here for completeness.
namespace detail
{
    template<std::size_t>
    struct Any
    {
        template<class T> Any(T&&) {}
    };
    template<typename T>
    struct wrapper {};
    template<std::size_t... Is>
    struct get_nth_helper
    {
        template<typename T>
        static T deduce(Any<Is>..., wrapper<T>, ...);
    };
    template<std::size_t... Is, typename... Ts>
    auto deduce_seq(seq<Is...>, wrapper<Ts>... pp)
    -> decltype( get_nth_helper<Is...>::deduce(pp...) );
}
#include <tuple>
template<std::size_t n, class Tuple>
struct tuple_element;
template<std::size_t n, class... Ts>
struct tuple_element<n, std::tuple<Ts...>>
{
    using type = decltype( detail::deduce_seq(gen_seq<n>{},
                                              detail::wrapper<Ts>()...) );
};
Helper for last element:
template<typename Tuple>
struct tuple_last_element;
template<typename... Ts>
struct tuple_last_element<std::tuple<Ts...>>
{
    using type = typename tuple_element<sizeof...(Ts)-1,
                                        std::tuple<Ts...>> :: type;
};
Usage example:
#include <iostream>
#include <type_traits>
int main()
{
    std::tuple<int, bool, char const&> t{42, true, 'c'};
    tuple_last_element<decltype(t)>::type x = 'c'; // it's a reference
    static_assert(std::is_same<decltype(x), char const&>{}, "!");
}
Original version:
#include <tuple>
#include <type_traits>
namespace detail
{
    template<typename Seq, typename... TT>
    struct get_last_helper;
    template<std::size_t... II, typename... TT>
    struct get_last_helper< seq<II...>, TT... >
    {
        template<std::size_t I, std::size_t L, typename T>
        struct pack {};
        template<typename T, std::size_t L>
        struct pack<L, L, T>
        {
            T declval();
        };
        // this needs simplification..
        template<typename... TTpacked>
        struct exp : TTpacked...
        {
            static auto declval_helper()
                -> decltype(std::declval<exp>().declval());
            using type = decltype(declval_helper());
        };
        using type = typename exp<pack<II, sizeof...(TT)-1, TT>...>::type;
    };
}
template< typename Tuple >
struct get_last;
template< typename... TT >
struct get_last<std::tuple<TT...>>
{
    template<std::size_t... II>
    static seq<II...> helper(seq<II...>);
    using seq_t = decltype(helper(gen_seq<sizeof...(TT)>()));
    using type = typename detail::get_last_helper<seq_t, TT...>::type;
};
int main()
{
    using test_type = std::tuple<int, double, bool, char>;
    static_assert(std::is_same<char, get_last<test_type>::type>::value, "!");
    // fails:
    static_assert(std::is_same<int, get_last<test_type>::type>::value, "!");
}