結果
問題 | No.800 四平方定理 |
ユーザー | yukinon0808 |
提出日時 | 2019-03-18 00:06:18 |
言語 | C++11 (gcc 11.4.0) |
結果 |
CE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 18,210 bytes |
コンパイル時間 | 1,242 ms |
コンパイル使用メモリ | 156,748 KB |
最終ジャッジ日時 | 2024-11-14 21:20:35 |
合計ジャッジ時間 | 1,630 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
コンパイルメッセージ
main.cpp:9:21: error: ‘operator<<’ function uses ‘auto’ type specifier without trailing return type 9 | template<typename T>auto&operator<<(ostream&s,const vector<T>&v){s<<"[";bool a=1;for(auto e:v){s<<(a?"":" ")<<e;a=0;}s<<"]";return s;} | ^~~~ main.cpp:9:21: note: deduced return type only available with ‘-std=c++14’ or ‘-std=gnu++14’ main.cpp:10:32: error: ‘operator<<’ function uses ‘auto’ type specifier without trailing return type 10 | template<typename T,typename U>auto&operator<<(ostream&s,const pair<T,U>&p){s<<"("<<p.first<<","<<p.second<<")";return s;} | ^~~~ main.cpp:10:32: note: deduced return type only available with ‘-std=c++14’ or ‘-std=gnu++14’ main.cpp:11:21: error: ‘operator<<’ function uses ‘auto’ type specifier without trailing return type 11 | template<typename T>auto&operator<<(ostream&s,const set<T>&st){s<<"{";bool a=1;for(auto e:st){s<<(a?"":" ")<<e;a=0;}s<<"}";return s;} | ^~~~ main.cpp:11:21: note: deduced return type only available with ‘-std=c++14’ or ‘-std=gnu++14’ main.cpp:12:32: error: ‘operator<<’ function uses ‘auto’ type specifier without trailing return type 12 | template<typename T,typename U>auto&operator<<(ostream&s,const map<T,U>&m){s<<"{";bool a=1;for(auto e:m){s<<(a?"":" ")<<e.first<<":"<<e.second;a=0;}s<<"}";return s;} | ^~~~ main.cpp:12:32: note: deduced return type only available with ‘-std=c++14’ or ‘-std=gnu++14’
ソースコード
#include <bits/stdc++.h> #define int long long int using namespace std; template<typename T,typename U> using P=pair<T,U>; template<typename T> using V=vector<T>; template<typename T>bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;} template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;} template<typename T>auto&operator<<(ostream&s,const vector<T>&v){s<<"[";bool a=1;for(auto e:v){s<<(a?"":" ")<<e;a=0;}s<<"]";return s;} template<typename T,typename U>auto&operator<<(ostream&s,const pair<T,U>&p){s<<"("<<p.first<<","<<p.second<<")";return s;} template<typename T>auto&operator<<(ostream&s,const set<T>&st){s<<"{";bool a=1;for(auto e:st){s<<(a?"":" ")<<e;a=0;}s<<"}";return s;} template<typename T,typename U>auto&operator<<(ostream&s,const map<T,U>&m){s<<"{";bool a=1;for(auto e:m){s<<(a?"":" ")<<e.first<<":"<<e.second;a=0;}s<<"}";return s;} #define DUMP(x) cerr<<#x<<" = "<<(x)<<endl; struct edge { int to, cost; }; const int INF = 1e18; const int MOD = 1e9+7; /// like std::equal_to but no need to #include <functional> template<typename T> struct HashMapEqualTo { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; } }; /// A cache-friendly hash table with open addressing, linear probing and power-of-two capacity template <typename KeyT, typename ValueT, typename HashT = std::hash<KeyT>, typename EqT = HashMapEqualTo<KeyT>> class HashMap { private: using MyType = HashMap<KeyT, ValueT, HashT, EqT>; using PairT = std::pair<KeyT, ValueT>; public: using size_type = size_t; using value_type = PairT; using reference = PairT&; using const_reference = const PairT&; class iterator { public: using iterator_category = std::forward_iterator_tag; using difference_type = size_t; using distance_type = size_t; using value_type = std::pair<KeyT, ValueT>; using pointer = value_type*; using reference = value_type&; iterator() { } iterator(MyType* hash_map, size_t bucket) : _map(hash_map), _bucket(bucket) { } iterator& operator++() { this->goto_next_element(); return *this; } iterator operator++(int) { size_t old_index = _bucket; this->goto_next_element(); return iterator(_map, old_index); } reference operator*() const { return _map->_pairs[_bucket]; } pointer operator->() const { return _map->_pairs + _bucket; } bool operator==(const iterator& rhs) const { // DCHECK_EQ_F(_map, rhs._map); return this->_bucket == rhs._bucket; } bool operator!=(const iterator& rhs) const { // DCHECK_EQ_F(_map, rhs._map); return this->_bucket != rhs._bucket; } private: void goto_next_element() { // DCHECK_LT_F(_bucket, _map->_num_buckets); do { _bucket++; } while (_bucket < _map->_num_buckets && _map->_states[_bucket] != State::FILLED); } //private: // friend class MyType; public: MyType* _map; size_t _bucket; }; class const_iterator { public: using iterator_category = std::forward_iterator_tag; using difference_type = size_t; using distance_type = size_t; using value_type = const std::pair<KeyT, ValueT>; using pointer = value_type*; using reference = value_type&; const_iterator() { } const_iterator(iterator proto) : _map(proto._map), _bucket(proto._bucket) { } const_iterator(const MyType* hash_map, size_t bucket) : _map(hash_map), _bucket(bucket) { } const_iterator& operator++() { this->goto_next_element(); return *this; } const_iterator operator++(int) { size_t old_index = _bucket; this->goto_next_element(); return const_iterator(_map, old_index); } reference operator*() const { return _map->_pairs[_bucket]; } pointer operator->() const { return _map->_pairs + _bucket; } bool operator==(const const_iterator& rhs) const { // DCHECK_EQ_F(_map, rhs._map); return this->_bucket == rhs._bucket; } bool operator!=(const const_iterator& rhs) const { // DCHECK_EQ_F(_map, rhs._map); return this->_bucket != rhs._bucket; } private: void goto_next_element() { // DCHECK_LT_F(_bucket, _map->_num_buckets); do { _bucket++; } while (_bucket < _map->_num_buckets && _map->_states[_bucket] != State::FILLED); } //private: // friend class MyType; public: const MyType* _map; size_t _bucket; }; // ------------------------------------------------------------------------ HashMap() = default; HashMap(const HashMap& other) { reserve(other.size()); insert(other.cbegin(), other.cend()); } HashMap(HashMap&& other) { *this = std::move(other); } HashMap& operator=(const HashMap& other) { clear(); reserve(other.size()); insert(other.cbegin(), other.cend()); return *this; } void operator=(HashMap&& other) { this->swap(other); } ~HashMap() { for (size_t bucket=0; bucket<_num_buckets; ++bucket) { if (_states[bucket] == State::FILLED) { _pairs[bucket].~PairT(); } } free(_states); free(_pairs); } void swap(HashMap& other) { std::swap(_hasher, other._hasher); std::swap(_eq, other._eq); std::swap(_states, other._states); std::swap(_pairs, other._pairs); std::swap(_num_buckets, other._num_buckets); std::swap(_num_filled, other._num_filled); std::swap(_max_probe_length, other._max_probe_length); std::swap(_mask, other._mask); } // ------------------------------------------------------------- iterator begin() { size_t bucket = 0; while (bucket<_num_buckets && _states[bucket] != State::FILLED) { ++bucket; } return iterator(this, bucket); } const_iterator cbegin() const { size_t bucket = 0; while (bucket<_num_buckets && _states[bucket] != State::FILLED) { ++bucket; } return const_iterator(this, bucket); } const_iterator begin() const { return cbegin(); } iterator end() { return iterator(this, _num_buckets); } const_iterator cend() const { return const_iterator(this, _num_buckets); } const_iterator end() const { return cend(); } size_t size() const { return _num_filled; } bool empty() const { return _num_filled==0; } // Returns the number of buckets. size_t bucket_count() const { return _num_buckets; } /// Returns average number of elements per bucket. float load_factor() const { return static_cast<float>(_num_filled) / static_cast<float>(_num_buckets); } // ------------------------------------------------------------ template<typename KeyLike> iterator find(const KeyLike& key) { auto bucket = this->find_filled_bucket(key); if (bucket == (size_t)-1) { return this->end(); } return iterator(this, bucket); } template<typename KeyLike> const_iterator find(const KeyLike& key) const { auto bucket = this->find_filled_bucket(key); if (bucket == (size_t)-1) { return this->end(); } return const_iterator(this, bucket); } template<typename KeyLike> bool contains(const KeyLike& k) const { return find_filled_bucket(k) != (size_t)-1; } template<typename KeyLike> size_t count(const KeyLike& k) const { return find_filled_bucket(k) != (size_t)-1 ? 1 : 0; } /// Returns the matching ValueT or nullptr if k isn't found. template<typename KeyLike> ValueT* try_get(const KeyLike& k) { auto bucket = find_filled_bucket(k); if (bucket != (size_t)-1) { return &_pairs[bucket].second; } else { return nullptr; } } /// Const version of the above template<typename KeyLike> const ValueT* try_get(const KeyLike& k) const { auto bucket = find_filled_bucket(k); if (bucket != (size_t)-1) { return &_pairs[bucket].second; } else { return nullptr; } } /// Convenience function. template<typename KeyLike> const ValueT get_or_return_default(const KeyLike& k) const { const ValueT* ret = try_get(k); if (ret) { return *ret; } else { return ValueT(); } } // ----------------------------------------------------- /// Returns a pair consisting of an iterator to the inserted element /// (or to the element that prevented the insertion) /// and a bool denoting whether the insertion took place. std::pair<iterator, bool> insert(const KeyT& key, const ValueT& value) { check_expand_need(); auto bucket = find_or_allocate(key); if (_states[bucket] == State::FILLED) { return { iterator(this, bucket), false }; } else { _states[bucket] = State::FILLED; new(_pairs + bucket) PairT(key, value); _num_filled++; return { iterator(this, bucket), true }; } } std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT>& p) { return insert(p.first, p.second); } void insert(const_iterator begin, const_iterator end) { // TODO: reserve space exactly once. for (; begin != end; ++begin) { insert(begin->first, begin->second); } } /// Same as above, but contains(key) MUST be false void insert_unique(KeyT&& key, ValueT&& value) { // DCHECK_F(!contains(key)); check_expand_need(); auto bucket = find_empty_bucket(key); _states[bucket] = State::FILLED; new(_pairs + bucket) PairT(std::move(key), std::move(value)); _num_filled++; } void insert_unique(std::pair<KeyT, ValueT>&& p) { insert_unique(std::move(p.first), std::move(p.second)); } void insert_or_assign(const KeyT& key, ValueT&& value) { check_expand_need(); auto bucket = find_or_allocate(key); // Check if inserting a new value rather than overwriting an old entry if (_states[bucket] == State::FILLED) { _pairs[bucket].second = value; } else { _states[bucket] = State::FILLED; new(_pairs + bucket) PairT(key, value); _num_filled++; } } /// Return the old value or ValueT() if it didn't exist. ValueT set_get(const KeyT& key, const ValueT& new_value) { check_expand_need(); auto bucket = find_or_allocate(key); // Check if inserting a new value rather than overwriting an old entry if (_states[bucket] == State::FILLED) { ValueT old_value = _pairs[bucket].second; _pairs[bucket] = new_value.second; return old_value; } else { _states[bucket] = State::FILLED; new(_pairs + bucket) PairT(key, new_value); _num_filled++; return ValueT(); } } /// Like std::map<KeyT,ValueT>::operator[]. ValueT& operator[](const KeyT& key) { check_expand_need(); auto bucket = find_or_allocate(key); /* Check if inserting a new value rather than overwriting an old entry */ if (_states[bucket] != State::FILLED) { _states[bucket] = State::FILLED; new(_pairs + bucket) PairT(key, ValueT()); _num_filled++; } return _pairs[bucket].second; } // ------------------------------------------------------- /// Erase an element from the hash table. /// return false if element was not found bool erase(const KeyT& key) { auto bucket = find_filled_bucket(key); if (bucket != (size_t)-1) { _states[bucket] = State::ACTIVE; _pairs[bucket].~PairT(); _num_filled -= 1; return true; } else { return false; } } /// Erase an element using an iterator. /// Returns an iterator to the next element (or end()). iterator erase(iterator it) { // DCHECK_EQ_F(it._map, this); // DCHECK_LT_F(it._bucket, _num_buckets); _states[it._bucket] = State::ACTIVE; _pairs[it._bucket].~PairT(); _num_filled -= 1; return ++it; } /// Remove all elements, keeping full capacity. void clear() { for (size_t bucket=0; bucket<_num_buckets; ++bucket) { if (_states[bucket] == State::FILLED) { _states[bucket] = State::INACTIVE; _pairs[bucket].~PairT(); } } _num_filled = 0; _max_probe_length = -1; } /// Make room for this many elements void reserve(size_t num_elems) { size_t required_buckets = num_elems + num_elems/2 + 1; if (required_buckets <= _num_buckets) { return; } size_t num_buckets = 4; while (num_buckets < required_buckets) { num_buckets *= 2; } auto new_states = (State*)malloc(num_buckets * sizeof(State)); auto new_pairs = (PairT*)malloc(num_buckets * sizeof(PairT)); if (!new_states || !new_pairs) { free(new_states); free(new_pairs); throw std::bad_alloc(); } //auto old_num_filled = _num_filled; auto old_num_buckets = _num_buckets; auto old_states = _states; auto old_pairs = _pairs; _num_filled = 0; _num_buckets = num_buckets; _mask = _num_buckets - 1; _states = new_states; _pairs = new_pairs; std::fill_n(_states, num_buckets, State::INACTIVE); _max_probe_length = -1; for (size_t src_bucket=0; src_bucket<old_num_buckets; src_bucket++) { if (old_states[src_bucket] == State::FILLED) { auto& src_pair = old_pairs[src_bucket]; auto dst_bucket = find_empty_bucket(src_pair.first); // DCHECK_NE_F(dst_bucket, (size_t)-1); // DCHECK_NE_F(_states[dst_bucket], State::FILLED); _states[dst_bucket] = State::FILLED; new(_pairs + dst_bucket) PairT(std::move(src_pair)); _num_filled += 1; src_pair.~PairT(); } } //DCHECK_EQ_F(old_num_filled, _num_filled); free(old_states); free(old_pairs); } private: // Can we fit another element? void check_expand_need() { reserve(_num_filled + 1); } // Find the bucket with this key, or return (size_t)-1 template<typename KeyLike> size_t find_filled_bucket(const KeyLike& key) const { if (empty()) { return (size_t)-1; } // Optimization auto hash_value = _hasher(key); for (int offset=0; offset<=_max_probe_length; ++offset) { auto bucket = (hash_value + offset) & _mask; if (_states[bucket] == State::FILLED) { if (_eq(_pairs[bucket].first, key)) { return bucket; } } else if (_states[bucket] == State::INACTIVE) { return (size_t)-1; // End of the chain! } } return (size_t)-1; } // Find the bucket with this key, or return a good empty bucket to place the key in. // In the latter case, the bucket is expected to be filled. size_t find_or_allocate(const KeyT& key) { auto hash_value = _hasher(key); size_t hole = (size_t)-1; int offset=0; for (; offset<=_max_probe_length; ++offset) { auto bucket = (hash_value + offset) & _mask; if (_states[bucket] == State::FILLED) { if (_eq(_pairs[bucket].first, key)) { return bucket; } } else if (_states[bucket] == State::INACTIVE) { return bucket; } else { // ACTIVE: keep searching if (hole == (size_t)-1) { hole = bucket; } } } // No key found - but maybe a hole for it // DCHECK_EQ_F(offset, _max_probe_length+1); if (hole != (size_t)-1) { return hole; } // No hole found within _max_probe_length for (; ; ++offset) { auto bucket = (hash_value + offset) & _mask; if (_states[bucket] != State::FILLED) { _max_probe_length = offset; return bucket; } } } // key is not in this map. Find a place to put it. size_t find_empty_bucket(const KeyT& key) { auto hash_value = _hasher(key); for (int offset=0; ; ++offset) { auto bucket = (hash_value + offset) & _mask; if (_states[bucket] != State::FILLED) { if (offset > _max_probe_length) { _max_probe_length = offset; } return bucket; } } } private: enum class State : uint8_t { INACTIVE, // Never been touched ACTIVE, // Is inside a search-chain, but is empty FILLED // Is set with key/value }; HashT _hasher; EqT _eq; State* _states = nullptr; PairT* _pairs = nullptr; size_t _num_buckets = 0; size_t _num_filled = 0; int _max_probe_length = -1; // Our longest bucket-brigade is this long. ONLY when we have zero elements is this ever negative (-1). size_t _mask = 0; // _num_buckets minus one }; signed main() { int N, D; cin >> N >> D; HashMap<int,int> cnt; for (int x = 1; x <= N; x++) { for (int y = 1; y <= N; y++) { cnt[x*x + y*y]++; } } int ans = 0; for (int z = 1; z <= N; z++) { for (int w = 1; w <= N; w++) { ans += cnt[w*w - z*z + D]; } } cout << ans << endl; return 0; }