Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add rhstring #102

Merged
merged 10 commits into from
Feb 28, 2024
Merged

add rhstring #102

merged 10 commits into from
Feb 28, 2024

Conversation

shogo314
Copy link
Member

@shogo314
Copy link
Member Author

shogo314 commented Jan 19, 2024

初期化時に、コンテナじゃないやつ(charなど)が与えられた場合に、1文字だと解釈できるようにしてもいい
書き方がよくわからなかった

@shogo314
Copy link
Member Author

RollingHashはstaticにした方がよかったかもしれません

@Raclamusi
Copy link
Contributor

初期化時に、コンテナじゃないやつ(charなど)が与えられた場合に、1文字だと解釈できるようにしてもいい 書き方がよくわからなかった

C++20 を要求するなら

#include <ranges>

template <std::ranges::range R>
RHString(RollingHash& rh, R&& s);  // コンテナ用

template <class T>
RHString(RollingHash& rh, T&& x);  // それ以外用

でいいんですが、C++17 対応を続けるなら

// cpp/traits.hpp
#pragma once

#include <iterator>
#include <utility>
#include <type_traits>

namespace detail {
    using std::begin, std::end;

    template <class T, class = void>
    struct is_range_impl : std::false_type {};
    template <class T>
    struct is_range_impl<T, std::void_t<decltype(begin(std::declval<T&>()), end(std::declval<T&>()))>> : std::true_type {};
}

template <class T>
struct is_range : detail::is_range_impl<T>::type {};
template <class T>
inline constexpr bool is_range_v = is_range<T>::value;

// cpp/rolling-hash.hpp
#include "traits.hpp"

template <class R, class = std::enable_if_t<is_range_v<R>>>
RHString(RollingHash& rh, R&& s);  // コンテナ用

template <class T, class = std::enable_if_t<not is_range_v<T>>>
RHString(RollingHash& rh, T&& x);  // それ以外用

でできます( is_range はほかでも使いそうだと思ってファイル分割する例を示しましたが、別にファイル分割する必要はないです)。

@KowerKoint
Copy link
Contributor

ICPCがC++20対応したのでそろそろC++20で書きたい気持ちはわかるんですが、AOJがまだなのでまだC++17限定でお願いしたいです

Copy link
Contributor

@KowerKoint KowerKoint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

よさそう、ありがとうございます
operator=などで普通の文字列や文字を受け取れるようになると少し嬉しいです
std::stringとかstd::vector<unsigned long long>とか(欲を言えばstd::deque<unsigned long long>)で生の文字列自体も持てるようにすると、区間取得や一要素変更に対応できるようになるのでverifyの問題もセグ木が要らなくなって最高です(pop_backをやろうとするとmod 2^61-1の除算とかが出てきて実装が重くなるので適当なところで妥協してもらってもいいです)

@shogo314
Copy link
Member Author

=についてはassignを実装したからいいかと思ってましたが、あっても困らないので書きます。
文字列をもつようにすると+がO(1)でできなくなって問題じゃないですか?
abc331_fをセグ木を使わずに解く方法、よくわかってないです。

@KowerKoint
Copy link
Contributor

文字列をもつようにすると+がO(1)でできなくなって問題じゃないですか?

たしかに。
セグ木もいりますね…なにもありません

@shogo314
Copy link
Member Author

作業の続きは期末が終わってからやります
C++20については個人的にはCodeChefの対応も待ちたい
C++17が使えないサイトは見たことないけど、C++20未対応はたまにある印象

@shogo314
Copy link
Member Author

いっそセグ木も一緒にライブラリにしてしまえばいい気がしてきました

@shogo314
Copy link
Member Author

迷ったけど実装しなかったもの

  • operator+=(RHString以外)
  • append
  • push_back

Copy link
Contributor

@KowerKoint KowerKoint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

いい感じです。

@KowerKoint KowerKoint merged commit 476e5dd into main Feb 28, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants