├── .gitignore ├── test ├── Makefile ├── MemPool_Speed.cpp ├── fc.h ├── Sort_Speed.cpp ├── make.py ├── SharedPtr_Correct.cpp ├── BIT_SegmentTree_Correct.cpp ├── vEBTree_BIT_Speed.cpp ├── Heap.cpp ├── SequenceContainer_Speed.cpp ├── LuoguP3377LeftistTree.cpp ├── Map_Speed.cpp └── LuoguP3371Dijkstra-FibHeap.cpp ├── toy ├── Profiler.h ├── Ptr32.h ├── template │ ├── ArrayT.h │ ├── RefWrapper.h │ ├── Function.h │ ├── TypeName.h │ ├── SetT.h │ ├── ListT.h │ └── SIUnit.h ├── PersistentArray.h ├── legacy │ ├── SegmentTreeUtil.h │ ├── SegmentTree.h │ └── vEBTree-pointer.h ├── MemPool.h ├── SharedPtr.h ├── Complexity.h ├── IntrusiveList.h ├── KDTree.h ├── PersistentTreap.h ├── TimSort.h ├── DynamicSegTree.h ├── Trie.h ├── WBT.h ├── Calculator.h └── Polynomial.h ├── heap ├── PriorityQueue.h ├── LeftistTree.h ├── MinMaxHeap.h ├── FibHeap.h └── PairingHeap.h ├── integer ├── BIT.h ├── BITTree.h ├── BitSet.h ├── vEBTree.h ├── UInt.h └── BigInt.h ├── associative ├── HashMapUtil.h ├── TreeUtil.h ├── SkipList.h ├── Treap.h ├── Splay.h ├── AVL.h └── HashMap-OpenAddress.h ├── Util.h └── sequential ├── Vector.h ├── String.h ├── ForwardList.h └── Deque.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.exe 3 | *.o 4 | *.txt 5 | .idea 6 | .vscode 7 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | SOURCE = $(wildcard *.cpp) 2 | TARGET = $(SOURCE:%.cpp=%.exe) 3 | 4 | all : $(TARGET) 5 | 6 | %.exe : %.cpp 7 | -g++ $< -o $@ 8 | 9 | .PNONY : all clean 10 | 11 | clean : 12 | rm *.exe 13 | -------------------------------------------------------------------------------- /toy/Profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace ds 4 | { 5 | class Profiler 6 | { 7 | typedef std::chrono::high_resolution_clock Timer; 8 | typedef decltype(Timer::now()) ClockType; 9 | ClockType beg; 10 | public: 11 | Profiler() :beg(Timer::now()) {} 12 | decltype((beg - beg).count()) reset() 13 | { 14 | auto ret = Timer::now() - beg; 15 | beg = Timer::now(); 16 | return ret.count(); 17 | } 18 | }; 19 | } -------------------------------------------------------------------------------- /test/MemPool_Speed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../MemPool.h" 6 | using namespace std; 7 | using namespace ds; 8 | const int maxn = 5e6; 9 | template 10 | void test(const char *name) 11 | { 12 | cout << name << endl; 13 | clock_t beg = clock(); 14 | { 15 | L lst; 16 | for (int i = 0; i < maxn; ++i) 17 | lst.push_back(i), lst.push_front(i); 18 | } 19 | cout << clock() - beg << endl; 20 | } 21 | 22 | int main() 23 | { 24 | test>>("list>"); 25 | test>("list"); 26 | } -------------------------------------------------------------------------------- /test/fc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace ds 7 | { 8 | inline int fc(const char *f1,const char *f2) 9 | { 10 | FILE *file1 = fopen(f1,"r"), *file2 = fopen(f2, "r"); 11 | fseek(file1, 0, SEEK_END), fseek(file2, 0, SEEK_END); 12 | int len1 = ftell(file1) + 100, len2 = ftell(file2) + 100; 13 | fseek(file1, 0, SEEK_SET), fseek(file2, 0, SEEK_SET); 14 | char *cont1 = (char *)calloc(len1, 1), *cont2 = (char *)calloc(len2, 1); 15 | fread(cont1, 1, len1, file1), fread(cont2, 1, len2, file2); 16 | int ret = strcmp(cont1, cont2); 17 | free(cont1), free(cont2); 18 | fclose(file1), fclose(file2); 19 | return ret; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/Sort_Speed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Algorithm.h" 5 | #include "../TimSort.h" 6 | #include "../BTree.h" 7 | #include "../Util.h" 8 | using namespace std; 9 | using namespace ds; 10 | 11 | const int maxn = 5e7; 12 | int a[maxn]; 13 | int input[maxn]; 14 | template 15 | void test(Sorter s, const char *name) 16 | { 17 | cout << name << endl; 18 | memcpy(a, input, sizeof input); 19 | clock_t beg = clock(); 20 | s(a, a + maxn); 21 | cout << clock() - beg << endl; 22 | cout << "correct? " << boolalpha << is_sorted(a, a + maxn) << endl; 23 | } 24 | int main() 25 | { 26 | for (int i = 0; i < maxn; ++i) 27 | input[i] = rani(1, 1e9); 28 | cout << "press to begin" << endl; 29 | getchar(); 30 | 31 | test(std::sort, "std::sort"); 32 | test(std::stable_sort, "std::stable_sort"); 33 | test(ds::sort, "ds::sort"); 34 | test(ds::stable_sort, "ds::stable_sort"); 35 | test(ds::radixSort, "ds::radixSort"); 36 | } 37 | -------------------------------------------------------------------------------- /test/make.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import re 4 | import time 5 | matchCpp = re.compile(r".*\.cpp") 6 | matchExe = re.compile(r".*\.exe") 7 | matchTxt = re.compile(r".*\.txt") 8 | 9 | def toCompileCommand(file): 10 | return "g++ -std=c++17 -O2 " + file + " -o " + file[:-3]+"exe" 11 | def main(): 12 | command = "" 13 | if len(sys.argv) == 2: 14 | command = sys.argv[1] 15 | else: 16 | command = "build" 17 | if command == "build": 18 | if (len(sys.argv) >= 3): 19 | shellCommand = toCompileCommand(sys.argv[2]) 20 | print(shellCommand) 21 | os.system(shellCommand) 22 | else: 23 | for file in list(os.walk("."))[0][2]: 24 | if matchCpp.match(file): 25 | shellCommand = toCompileCommand(file) 26 | print(shellCommand) 27 | os.system(shellCommand) 28 | time.sleep(2) 29 | elif command == "clean": 30 | for file in list(os.walk("."))[0][2]: 31 | if matchExe.match(file) or matchTxt.match(file): 32 | os.remove(file) 33 | else: 34 | print("invalid argument ")+command 35 | 36 | 37 | if __name__ == '__main__': 38 | main() 39 | -------------------------------------------------------------------------------- /heap/PriorityQueue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Algorithm.h" 3 | #include "Vector.h" 4 | namespace ds 5 | { 6 | template ,typename Container=Vector > 7 | class PriorityQueue 8 | { 9 | public: 10 | typedef K value_type; 11 | typedef K *iterator; 12 | typedef K *pointer; 13 | typedef K &reference; 14 | typedef const K &const_reference; 15 | typedef const K *const_iterator; 16 | typedef const K *const_pointer; 17 | private: 18 | Comp comp; 19 | Container container; 20 | public: 21 | explicit PriorityQueue(Comp comp = Comp()) : comp(comp) {} 22 | reference operator[](int x) { return container[x]; } 23 | const_reference top() const { return container[0]; } 24 | void pop() 25 | { 26 | container[0] = container[container.size() - 1]; 27 | container.pop_back(); 28 | ds::fixHeap_(container.begin(), comp, 0, container.size()); 29 | } 30 | void push(const K &key) 31 | { 32 | container.push_back(key); 33 | ds::push_heap(container.begin(), container.end(), comp); 34 | } 35 | void replaceFirst(const K &key) 36 | { 37 | container[0] = key; 38 | ds::fixHeap_(container.begin(), comp, 0, container.size()); 39 | } 40 | bool empty()const { return container.empty(); } 41 | int size()const { return container.size(); } 42 | }; 43 | } -------------------------------------------------------------------------------- /test/SharedPtr_Correct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../SharedPtr.h" 4 | #include 5 | using namespace std; 6 | using namespace ds; 7 | // const int maxn = 2000; 8 | // template 9 | // void test() 10 | // { 11 | // L *l2; 12 | // { 13 | // clock_t beg = clock(); 14 | // L lst; 15 | // for (int i = 0; i < maxn; ++i) 16 | // lst.push_back(i); 17 | // cout << clock() - beg << endl; 18 | // } 19 | // getchar(); 20 | // } 21 | 22 | struct A 23 | { 24 | static int cnt; 25 | int _cnt_; 26 | double x; 27 | virtual void foo() const 28 | { 29 | cout << "A\n"; 30 | } 31 | virtual ~A() 32 | { 33 | ++cnt; 34 | cout << "A destroy\n"; 35 | } 36 | }; 37 | int A::cnt = 0; 38 | 39 | struct B : A 40 | { 41 | double xx; 42 | void foo() const override 43 | { 44 | cout << "B\n"; 45 | } 46 | ~B() override 47 | { 48 | cout << "B destroy\n"; 49 | } 50 | }; 51 | 52 | int main() 53 | { 54 | { 55 | SharedPtr pa(new B); 56 | pa->foo(); 57 | 58 | auto pa1 = pa; 59 | auto pa2 = move(pa); 60 | SharedPtr pa3 = nullptr; 61 | if (!pa3) 62 | pa3 = pa2; 63 | swap(pa1, pa2); 64 | pa1 = makeShared(); 65 | pa2 = pa3 = pa1; //此时之前的B应该析构 66 | pa3->foo(); 67 | } 68 | cout << A::cnt; 69 | } -------------------------------------------------------------------------------- /integer/BIT.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | namespace ds 3 | { 4 | /* 5 | *树状数组拓展 6 | *1.区间修改单点求和:维护差分数组,b[i]:=a[i]-a[i-1] 7 | *修改:只需修改两个b;求值:求b[1] to b[x]的和 8 | *2.区间修改区间求和:同样基于上面的原理 9 | *求值:a[1]+...+a[x] = b[1]*x + b[2]*(x-1) +...+ b[x] 10 | *=(b[1]+...+b[x])*x-(b[1]*0+b[2]*1+...+b[x]*(x-1)) 11 | *需维护b[i]*(i-1)数组,维护的时候也只用修改两个点 12 | *3.模拟平衡树:见BITTree.h 13 | *插入+1/删除-1 14 | *前驱/后继/kth => 二分 O(lg^2(n)),但是常数小 15 | */ 16 | //[1,N] indexed 17 | template 18 | class BIT 19 | { 20 | int arr[N + 1] = { 0 }; 21 | struct Reference 22 | { 23 | BIT *self; 24 | int pos; 25 | void operator+=(int d) { self->add(pos, d); } 26 | void operator-=(int d) { self->add(pos, -d); } 27 | int operator-(const Reference &rhs) const { return self->query(rhs.pos, pos); } 28 | }; 29 | protected: 30 | int n; 31 | public: 32 | BIT(int n = N) :n(n) {} 33 | int sum(int pos) const 34 | { 35 | int ret = 0; 36 | while (pos) 37 | { 38 | ret += arr[pos]; 39 | pos &= pos - 1; //等价于pos -= pos & -pos 40 | } 41 | return ret; 42 | } 43 | int query(int l,int r) const 44 | { 45 | //查询[l,r]间的和,需要sum到l-1 46 | return sum(r) - sum(l - 1); 47 | } 48 | void add(int pos,int d) 49 | { 50 | while (pos <= n) 51 | { 52 | arr[pos] += d; 53 | pos += pos & -pos; 54 | } 55 | } 56 | Reference operator[](int pos) { return { this,pos }; } 57 | }; 58 | } -------------------------------------------------------------------------------- /test/BIT_SegmentTree_Correct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../DynamicSegTree.h" 3 | #include "../BITTree.h" 4 | #include "../fc.h" 5 | #include "../Util.h" 6 | using namespace std; 7 | using namespace ds; 8 | const int N = 10000; 9 | DynamicSegTree<100000> tr(1, N); 10 | BITTree bit; 11 | int main() 12 | { 13 | for (int i = 0; i < N * 2; ++i) 14 | { 15 | int x = rani(1, N); 16 | tr.insert(x); 17 | bit.insert(x); 18 | } 19 | for (int i = 0; i < N; ++i) 20 | { 21 | int x = rani(1, N); 22 | tr.erase(x); 23 | bit.erase(x); 24 | } 25 | freopen("bit.txt", "w", stdout); 26 | for (int i = bit.findMin(); ~i; i = bit.findNext(i)) 27 | cout << i; 28 | for (int i = bit.findMin(); ~i; i = bit.findPrev(i)) 29 | cout << i; 30 | for (int i = 1, sz = bit.size(); i <= sz; ++i) 31 | cout << bit.kth(i); 32 | for (int i = bit.findMin(), mx = bit.findMax(); i <= mx; ++i) 33 | cout << bit.rank(i); 34 | 35 | 36 | freopen("segtree.txt", "w", stdout); 37 | for (int i = tr.findMin(); ~i; i = tr.findNext(i)) 38 | cout << i; 39 | for (int i = tr.findMin(); ~i; i = tr.findPrev(i)) 40 | cout << i; 41 | for (int i = 1, sz = tr.size(); i <= sz; ++i) 42 | cout << tr.kth(i); 43 | for (int i = tr.findMin(), mx = tr.findMax(); i <= mx; ++i) 44 | cout << tr.rank(i); 45 | 46 | freopen("con", "w", stdout); 47 | 48 | cout <<"result(0 for correct):" < 3 | namespace ds 4 | { 5 | //注意,非常依赖于编译器和具体的机器 6 | //这里假定64位的指针只有后32位非0,很多情况下(如微软的编译器下)这都是不成立的 7 | template 8 | class Ptr32 9 | { 10 | public: 11 | typedef std::random_access_iterator_tag iterator_category; 12 | typedef K value_type; 13 | typedef int difference_type; 14 | typedef K *pointer; 15 | typedef K &reference; 16 | Ptr32(uint32_t ptr) : ptr(ptr) {} 17 | Ptr32(K *ptr64 = nullptr) :ptr(uint32_t(ptr64 - reinterpret_cast(nullptr))) {} 18 | Ptr32 &operator+=(int d) { return ptr += d, *this; } 19 | Ptr32 &operator-=(int d) { return operator+=(-d); } 20 | int operator-(const Ptr32 &rhs) const { return ptr - rhs.ptr; } 21 | Ptr32 operator+(int d) 22 | { 23 | Ptr32 tmp(ptr); 24 | return tmp += d; 25 | } 26 | Ptr32 operator-(int d) 27 | { 28 | Ptr32 tmp(ptr); 29 | return tmp -= d; 30 | } 31 | Ptr32 &operator++() { return operator+=(1); } 32 | Ptr32 operator++(int) 33 | { 34 | Ptr32 tmp(ptr); 35 | operator+=(1); 36 | return tmp; 37 | } 38 | Ptr32 &operator--() { return operator-=(1); } 39 | Ptr32 operator--(int) 40 | { 41 | Ptr32 tmp(ptr); 42 | operator-=(1); 43 | return tmp; 44 | } 45 | operator K *() const { return static_cast(nullptr) + ptr; } 46 | K &operator*() const { return **this; } 47 | K *operator->() const { return *this; } 48 | K &operator[](int index) const { return *(*this + index); } 49 | //注意,const版本的重载实际上是const pointer,不是pointer to const,所以直接返回K的指针或者引用 50 | //所以实际上不需要提供非const版本的重载 51 | private: 52 | uint32_t ptr = 0; 53 | }; 54 | } -------------------------------------------------------------------------------- /test/vEBTree_BIT_Speed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../Util.h" 4 | #include "../SkipList.h" 5 | #include "../Treap.h" 6 | #include "../vEBTree.h" 7 | #include "../BITTree.h" 8 | #include "../DynamicSegTree.h" 9 | using namespace std; 10 | using namespace ds; 11 | const int maxn = 2e6; 12 | int input[maxn]; 13 | bool exist[maxn]; 14 | int ordered[maxn]; 15 | template 16 | void test(const char *name, Args &&... args) 17 | { 18 | cout << name << endl; 19 | clock_t beg[5] = {clock()}; 20 | T *pt = new T(args...); 21 | cout << "build :" << -beg[0] + (beg[1] = clock()) << endl; 22 | for (int i = 0; i < maxn; ++i) 23 | pt->insert(input[i]); 24 | cout << "insert :" << -beg[1] + (beg[2] = clock()) << endl; 25 | for (int i = 0; i < maxn; ++i) 26 | exist[i] = pt->exist(input[i]); 27 | cout << "find :" << -beg[2] + (beg[3] = clock()) << endl; 28 | for (int i = pt->findMin(), cnt = 0; ~i; i = pt->findNext(i)) 29 | ordered[cnt++] = i; 30 | for (int i = pt->findMax(), cnt = 0; ~i; i = pt->findPrev(i)) 31 | ordered[cnt++] = i; 32 | cout << "prev/next :" << -beg[3] + (beg[4] = clock()) << endl; 33 | for (int i = 0; i < maxn; ++i) 34 | pt->erase(input[i]); 35 | cout << "erase :" << -beg[4] + clock() << endl; 36 | cout << "all :" << clock() - beg[0] << endl; 37 | 38 | delete pt; 39 | } 40 | int main() 41 | { 42 | for (int i = 0; i < maxn; ++i) 43 | input[i] = i + 1; 44 | random_shuffle(input, input + maxn); 45 | 46 | test>("BITTree<2000000>"); 47 | test>("vEBTree<21>"); 48 | } 49 | -------------------------------------------------------------------------------- /toy/template/ArrayT.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ds 5 | { 6 | template 7 | struct ArrayT 8 | { 9 | private: 10 | constexpr static T elems[sizeof...(Elems)] = { Elems... }; 11 | public: 12 | constexpr T operator[](int index) { return elems[index]; } 13 | constexpr static int size() { return sizeof...(Elems); } 14 | template 15 | constexpr auto operator+(ArrayT rhs) const 16 | { 17 | return ArrayT{}; 18 | } 19 | }; 20 | template 21 | using CArrayT = ArrayT; 22 | 23 | // template 24 | // struct ParseStr 25 | // { 26 | // constexpr static auto name =/* ParseStr::name + */ CArrayT{}; 27 | // }; 28 | // template 29 | // struct ParseStr::type> 30 | // { 31 | // constexpr static auto name = CArrayT<*Str>{}; 32 | // }; 33 | 34 | template 35 | struct ParseUInt 36 | { 37 | constexpr static auto name = ParseUInt::name + ArrayT{}; 38 | }; 39 | template 40 | struct ParseUInt::type> 41 | { 42 | constexpr static auto name = ArrayT{}; 43 | }; 44 | 45 | template 46 | std::ostream& operator<<(std::ostream &os, ArrayT arr) 47 | { 48 | for (int i = 0; i < arr.size(); ++i) 49 | os << arr[i] << ' '; 50 | return os; 51 | } 52 | template 53 | std::ostream& operator<<(std::ostream &os, ArrayT arr) 54 | { 55 | for (int i = 0; i < arr.size(); ++i) 56 | os << arr[i]; 57 | return os; 58 | } 59 | } -------------------------------------------------------------------------------- /test/Heap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../Util.h" 7 | #include "../Deque.h" 8 | #include "../Vector.h" 9 | #include "../PriorityQueue.h" 10 | #include "../LeftistTree.h" 11 | #include "../FibHeap.h" 12 | #include "../MinMaxHeap.h" 13 | #include "../PairingHeap.h" 14 | 15 | using namespace std; 16 | using namespace ds; 17 | 18 | const int maxn = 5e6; 19 | int input[maxn], a[maxn]; 20 | template 21 | void test(const char *name) 22 | { 23 | cout << name << endl; 24 | PQ pq; 25 | clock_t beg = clock(); 26 | for (int i = 0; i < maxn; ++i) 27 | pq.push(input[i]); 28 | if constexpr (!std::is_same_v>) 29 | { 30 | int pos = 0; 31 | while (!pq.empty()) 32 | { 33 | a[pos++] = pq.top(); 34 | pq.pop(); 35 | } 36 | } 37 | else 38 | { 39 | int head = 0, tail = maxn - 1; 40 | while (!pq.empty()) 41 | { 42 | a[head++] = pq.min(); 43 | pq.popMin(); 44 | a[tail--] = pq.max(); 45 | pq.popMax(); 46 | } 47 | } 48 | cout << clock() - beg << endl; 49 | cout << "correct? " << boolalpha << is_sorted(a, a + maxn) << endl; 50 | } 51 | int main() 52 | { 53 | for (int i = 0; i < maxn; ++i) 54 | input[i] = rani(1, 1e9); 55 | test, greater>>("std::priority_queue"); 56 | test>>("PriorityQueue(binary heap)"); 57 | test>("MinMaxHeap"); 58 | test>("PairingHeap"); 59 | test>("LeftistTree"); 60 | test>("FibHeap"); 61 | getchar(); 62 | } -------------------------------------------------------------------------------- /toy/template/RefWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace ds 4 | { 5 | //RefPair的目的是: 6 | //把引用像对象一样存下来,并且允许改变它指向的对象 7 | template ::value * 2 + !std::is_rvalue_reference::value> 8 | struct RefPair 9 | { 10 | F &first; 11 | S &second; 12 | //替换引用的对象 13 | void assign(const RefPair &rhs) { memcpy(this, &rhs, sizeof(RefPair)); } 14 | }; 15 | 16 | template 17 | struct RefPair 18 | { 19 | F first; 20 | S second; 21 | void assign(const RefPair &rhs) { *this = rhs; } 22 | }; 23 | 24 | template 25 | struct RefPair 26 | { 27 | F first; 28 | S &second; 29 | void assign(const RefPair &rhs) 30 | { 31 | first = rhs.first; 32 | //尝试获取引用的地址会得到引用指向的对象的地址,那样是错误的 33 | //引用的大小等同于指针的大小 34 | memcpy(&first + 1, &rhs.first + 1, sizeof(void *)); 35 | } 36 | }; 37 | 38 | template 39 | struct RefPair 40 | { 41 | F &first; 42 | S second; 43 | void assign(const RefPair &rhs) 44 | { 45 | memcpy(this, &rhs, sizeof(void *)); 46 | second = rhs.second; 47 | } 48 | }; 49 | 50 | template 51 | auto makeRefPair(F &&first,S &&second) 52 | { 53 | return RefPair{std::forward(first), std::forward(second)}; 54 | } 55 | 56 | template 57 | struct SmartRef 58 | { 59 | T &value; 60 | }; 61 | template 62 | struct SmartRef::value>> 63 | { 64 | T value; 65 | }; 66 | 67 | template 68 | auto makeRef(T &&value) 69 | { 70 | //如果value是右值,则T推断为 无任何修饰的类型,T&&为右值引用 71 | //否则T推断为左值引用,T&&经过引用折叠,等价于T& 72 | return SmartRef{std::forward(value)}; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /integer/BITTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "BIT.h" 3 | #include "Algorithm.h" 4 | namespace ds 5 | { 6 | //很显然,因为树状数组支持[1,N](业界习惯) 7 | //所以BITTree也只支持[1,N],要是想用[0,N)的话自觉在客户端-1吧 8 | //它支持所有平衡树操作(不像垃圾vEB),而且常数非常小 9 | //正常情况下可以吊打其他所有树(vEB除外),要是N实在太大还可以坐标离散化 10 | template 11 | struct BITTree : BIT 12 | { 13 | //所有函数的参数需自觉保证合法 14 | //应该不会有人故意传个负数进来吧(滑稽) 15 | BITTree(int n = N) :BIT(n) {} 16 | int count(int x) const { return BIT::query(x, x); } 17 | bool exist(int x) const { return count(x); } 18 | void insert(int x) 19 | { 20 | if (Multi || !count(x)) 21 | BIT::add(x, 1); 22 | } 23 | void erase(int x) 24 | { 25 | //Multi情况的erase是不明确的 26 | //比如说stl会整个抹掉,但是很多题目都要求只去掉一个 27 | if (count(x)) 28 | BIT::add(x, -1); 29 | } 30 | int findNext(int x) const //lg^2 31 | { 32 | int base = BIT::sum(x); 33 | if (BIT::sum(BIT::n) == base) 34 | return -1; 35 | return ds::bisearch(x + 1, BIT::n + 1, 36 | [=](int pos) {return BIT::sum(pos) > base; }); 37 | //这里会找到第一个[x+1,pos]间的和不为0的pos,于是的到后继 38 | } 39 | int findPrev(int x) const 40 | { 41 | int base = BIT::sum(x - 1); 42 | if (base == 0) 43 | return -1; 44 | return ds::bisearch(1, x, 45 | [=](int pos) {return BIT::sum(pos) == base; }); 46 | //返回第一个[1,pos]的和=[1,x-1]的和的pos 47 | //这样pos就是"引起最后一次改变"的位置,即前驱 48 | } 49 | int findMin() const { return findNext(0); } 50 | int findMax() const 51 | { 52 | if (exist(BIT::n)) 53 | return BIT::n; 54 | return findPrev(BIT::n); 55 | } 56 | int kth(int k) const 57 | { 58 | if (k > size() || k < 1) 59 | return -1; 60 | return ds::bisearch(1, BIT::n + 1 61 | , [=](int pos) {return BIT::sum(pos) >= k; }); 62 | } 63 | //不要求x存在 64 | int rank(int x) const { return BIT::sum(x - 1) + 1; } 65 | //求size需要lgN时间,最好保存下来 66 | int size() const { return BIT::sum(BIT::n); } 67 | }; 68 | } -------------------------------------------------------------------------------- /toy/PersistentArray.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | namespace ds 3 | { 4 | //下标是[1,N]indexed 5 | //版本是[0,MaxVersion)indexed 6 | template 7 | class PersistentArray 8 | { 9 | int roots[MaxVersion]; 10 | struct Node 11 | { 12 | int l, r; 13 | K key; 14 | }; 15 | Node tree[N * 4 + MaxVersion * 32]; //树的大小是O(N+MaxVer*lg(N)),O(N)是为了一开始建树的需要,lgN就用32来代替 16 | int size = 0; 17 | int build(int l, int r) 18 | { 19 | int root = ++size; 20 | int mid = (l + r) >> 1; 21 | if (l < r) 22 | { 23 | tree[root].l = build(l, mid); 24 | tree[root].r = build(mid + 1, r); 25 | } 26 | return root; 27 | } 28 | template 29 | int update(int pre, int l, int r, int where, Pred pred) 30 | { 31 | int root = ++size; 32 | tree[root].l = tree[pre].l; 33 | tree[root].r = tree[pre].r; 34 | int mid = (l + r) >> 1; 35 | if (l < r) 36 | { 37 | if (where <= mid) 38 | tree[root].l = update(tree[pre].l, l, mid, where, pred); 39 | else 40 | tree[root].r = update(tree[pre].r, mid + 1, r, where, pred); 41 | } 42 | else 43 | pred(tree[root].key); 44 | return root; 45 | } 46 | public: 47 | PersistentArray() { roots[0] = build(1, N); } 48 | K &query(int ver, int where) 49 | { 50 | int l = 1, r = N, cur = roots[ver]; 51 | while (l != r) 52 | { 53 | int mid = (l + r) >> 1; 54 | if (where <= mid) 55 | cur = tree[cur].l, r = mid; 56 | else 57 | cur = tree[cur].r, l = mid + 1; 58 | } 59 | return tree[cur].key; 60 | } 61 | template 62 | void update(int nver,int ver,int where,Pred pred) 63 | { 64 | roots[nver] = update(roots[ver], 1, N, where, pred); 65 | } 66 | void update(int nver, int ver, int where,const K &key) 67 | { 68 | roots[nver] = update(roots[ver], 1, N, where, 69 | [&](K &old) {old = key; }); 70 | } 71 | void update(int nver, int ver) { roots[nver] = roots[ver]; } 72 | }; 73 | } -------------------------------------------------------------------------------- /toy/legacy/SegmentTreeUtil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Util.h" 4 | namespace ds 5 | { 6 | namespace Seg 7 | { 8 | //放心,一个继承也不会有的,全是模板 9 | template 10 | struct Node 11 | { 12 | K key; 13 | K label; 14 | Node left; //不使用堆式储存 15 | Node right; 16 | template 17 | Node(Iter &it) : label(K()), left(it), right(it) 18 | { 19 | key = Func()(left.key, right.key); 20 | } 21 | }; 22 | template 23 | struct Node 24 | { 25 | //最底层的叶子并不需要标签 26 | K key; 27 | template 28 | Node(Iter &it) :key(*it++) {} //由于始终先初始化左边再初始化右边,故而初始化顺序与排列顺序相同 29 | }; 30 | struct InputIter 31 | { 32 | //一个常见的上述Iter的形式 33 | //注意模板参数N与实际范围n的区别,前者只是数据规模,不一定有那么多输入 34 | 35 | //remain被所有InputIter共享,因为上面的构造是传引用 36 | int remain; 37 | InputIter(int n) :remain(n) {} 38 | int operator*() const 39 | { 40 | if (remain != -1) 41 | return ds::read(); 42 | return 0; 43 | } 44 | InputIter operator++(int) { return --remain, *this; } 45 | InputIter &operator++() { return --remain, *this; } 46 | }; 47 | 48 | template 49 | struct FuncTraits {}; 50 | 51 | template<> 52 | struct FuncTraits> : std::plus 53 | { 54 | const static int zero = 0; 55 | static int rangeSum(int val, int len) { return val*len; } 56 | }; 57 | 58 | template<> 59 | struct FuncTraits> : ds::Min 60 | { 61 | const static int zero = INT_MAX; 62 | constexpr int rangeSum(int val, int len) { return val; } 63 | }; 64 | 65 | template<> 66 | struct FuncTraits> : ds::Max 67 | { 68 | const static int zero = INT_MIN; 69 | constexpr int rangeSum(int val, int len) { return val; } 70 | }; 71 | } 72 | } -------------------------------------------------------------------------------- /heap/LeftistTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace ds 4 | { 5 | //保证内存泄漏,没有拷贝控制,谁爱用谁用 6 | template 7 | class LeftistTree 8 | { 9 | public: 10 | struct Node 11 | { 12 | private: 13 | K key; 14 | int dist = 0; 15 | Node *p = nullptr; 16 | Node *left = nullptr, *right = nullptr; 17 | Node(const K &key) :key(key) {} 18 | public: 19 | const K &getKey()const { return key; } 20 | friend LeftistTree; 21 | }; 22 | private: 23 | Node *root = nullptr; 24 | LeftistTree(Node *root) :root(root) {} 25 | static int dist(Node *x) { return x ? x->dist : -1; } 26 | static Node *merge(Node *x,Node *y) 27 | { 28 | if (!x) return y; 29 | if (!y) return x; 30 | if (x->key > y->key) //小根 31 | std::swap(x, y); 32 | Node *tmp = merge(x->right, y); 33 | x->right = tmp, tmp->p = x; 34 | if (dist(x->right) > dist(x->left)) 35 | std::swap(x->left, x->right); 36 | x->dist = dist(x->right) + 1; 37 | return x; 38 | } 39 | public: 40 | LeftistTree() :root(nullptr) {} 41 | LeftistTree(const K &key) :root(new Node(key)) {} 42 | void merge(LeftistTree &rhs) 43 | { 44 | if (this != &rhs) 45 | { 46 | root = merge(root, rhs.root); 47 | rhs.root = nullptr; 48 | } 49 | } 50 | //请自觉保证树非空 51 | const K &top()const { return root->key; } 52 | void pop() 53 | { 54 | root = merge(root->left, root->right); 55 | } 56 | Node *push(const K&key) 57 | { 58 | Node *x = new Node(key); 59 | root = merge(root, x); 60 | return x; 61 | } 62 | void erase(Node *x) 63 | { 64 | Node *tmp = merge(x->left, x->right); 65 | if (!x->p) { root = tmp; return; } 66 | if (tmp) tmp->p = x->p;//本身x的两个孩子就是nullptr,所以tmp可能是nullptr 67 | if (x->p->right == x) x->p->right = tmp; 68 | else x->p->left = tmp; 69 | x = tmp; 70 | while (x && x->p) 71 | { 72 | if (dist(x->p->right) > dist(x->p->left)) 73 | std::swap(x->p->left, x->p->right); 74 | if (dist(x->p)==dist(x->p->right)+1) 75 | break; 76 | x->p->dist = dist(x->p->right) + 1; 77 | x = x->p; 78 | } 79 | } 80 | bool empty()const { return !root; } 81 | }; 82 | } -------------------------------------------------------------------------------- /toy/template/Function.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | //std::function在我看来很神奇 7 | //这里就模仿stl来实现一个,没有处理[函数对象太大时在堆上申请内存] 8 | namespace ds 9 | { 10 | template 11 | class FuncBase 12 | { 13 | public: 14 | virtual Ret operator()(Args&&...) = 0; 15 | virtual void clone(FuncBase *) const = 0; 16 | virtual ~FuncBase() {} 17 | }; 18 | 19 | template 20 | class FuncImpl : public FuncBase 21 | { 22 | typedef FuncBase Base; 23 | typedef FuncImpl Type; 24 | Func f_; //真正的可调用对象 25 | public: 26 | FuncImpl(const Func &f) : f_(f) {} 27 | Ret operator()(Args&&... args) override 28 | { 29 | return f_(std::forward(args)...); 30 | } 31 | void clone(Base *dest) const override 32 | { 33 | new(dest) Type(f_); 34 | } 35 | }; 36 | template 37 | class Function; 38 | 39 | template 40 | class Function 41 | { 42 | typedef FuncBase Base; 43 | Base *f_; //利用基类指针实现多态 44 | std::aligned_storage<3 * sizeof(void *)>::type buf_; 45 | //aligned_storage是开在栈上的,保证对齐的内存 46 | public: 47 | template 48 | Function(Func &&f, typename std::enable_if 49 | < //注意下面的remove_reference,因为is_same必须要求精确匹配(考虑universial reference的规则) 50 | !std::is_same::type, Function>::value 51 | >::type* = nullptr) //SFINAE,使得拷贝构造无法匹配这个函数 52 | { 53 | typedef FuncImpl::type, Ret, Args...> ImplType; 54 | //我之前一直不理解的地方在于,如何保存这个类型未知的对象 55 | //其实只需要在构造的时候给出类型信息,然后用一个具有动态性的指针来保存它就行了 56 | f_ = reinterpret_cast(&buf_); 57 | new(f_) ImplType(std::forward(f)); //直接构造,指针强转 58 | } 59 | Function(const Function &rhs) 60 | { 61 | //这时需要利用到多态构造函数,但是这其实是不存在的 62 | //用基类中的clone来代替 63 | f_ = reinterpret_cast(&buf_); 64 | rhs.f_->clone(f_); 65 | } 66 | Ret operator()(Args &&...args) 67 | { 68 | return f_->operator()(std::forward(args)...); 69 | } 70 | ~Function() 71 | { 72 | if (f_) 73 | f_->~Base(); 74 | } 75 | }; 76 | } 77 | -------------------------------------------------------------------------------- /associative/HashMapUtil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | namespace ds 3 | { 4 | //std::is_invocable是C++17标准提供的,MS的编译器没有实现 5 | //这里提供一个非常简单的实现,可能有很多情形都没有考虑到,但是够用了 6 | namespace detail 7 | { 8 | template 9 | struct CallableImpl 10 | { 11 | template ()(std::declval()...))> 12 | static std::true_type tryCall(int); 13 | template 14 | static std::false_type tryCall(...); 15 | }; 16 | } 17 | template 18 | struct Callable : decltype(detail::CallableImpl::tryCall(0)) {}; 19 | 20 | //这里对Chain还是OpenAddress的区分原则是:只要能够调用,就认为是哈希函数,就认为是使用Chain 21 | template , 22 | bool EnableOpenAddress = !Callable::value> 23 | class HashMap; 24 | 25 | 26 | template 27 | struct OpenAddress; 28 | struct Linear {}; 29 | struct Quadratic {}; 30 | struct Double {}; 31 | 32 | template 33 | struct OpenAddress 34 | { 35 | Hash hasher; 36 | typedef decltype(hasher(std::declval())) CodeType; 37 | CodeType cache; 38 | OpenAddress(const K&key) :cache(hasher(key)) {} 39 | CodeType probe(unsigned index) const { return cache + index; } 40 | }; 41 | template 42 | struct OpenAddress : Hash 43 | { 44 | Hash hasher; 45 | typedef decltype(hasher(std::declval())) CodeType; 46 | CodeType cache; 47 | OpenAddress(const K&key) :cache(hasher(key)) {} 48 | CodeType probe(unsigned index) const 49 | { 50 | //h(key,i) = (h0(key) + i * c1 + i^2 * c2) % m 51 | //为了保证探查序列取遍[0,m),一种可行的c1,c2,m取法是 52 | //c1=c2=0.5,m为2的幂 53 | return cache + index * (index + 1) / 2; 54 | } 55 | }; 56 | 57 | template 58 | struct OpenAddress 59 | { 60 | Hash1 hasher1; 61 | Hash2 hasher2; 62 | typedef decltype(hasher1(std::declval())) CodeType; 63 | CodeType cache1, cache2; 64 | OpenAddress(const K&key) :cache1(hasher1(key)),cache2(hasher2(key)) 65 | { 66 | //h(key,i) = (h1(key) + i * h2(key)) % m 67 | //为了保证探查序列取遍[0,m),必须保证h2与m互素 68 | //一种简单的实现是,令m为2的幂,h2返回奇数 69 | if ((cache2 & 1) == 0) 70 | throw std::runtime_error("Hash2 must return an odd number."); 71 | } 72 | CodeType probe(unsigned index) const { return cache1 + index * cache2; } 73 | }; 74 | } -------------------------------------------------------------------------------- /toy/template/TypeName.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ArrayT.h" 3 | namespace ds 4 | { 5 | template //for SFINAE 6 | struct TypeName { constexpr static CArrayT< 'u', 'n', 'd', 'e', 'f', 'i', 'n', 'e', 'd'> name{}; }; 7 | 8 | template <> struct TypeName { constexpr static CArrayT< 'i', 'n', 't'> name{}; }; 9 | template <> struct TypeName { constexpr static CArrayT< 'c', 'h', 'a', 'r'> name{}; }; 10 | template <> struct TypeName { constexpr static CArrayT< 'd', 'o', 'u', 'b', 'l', 'e'> name{}; }; 11 | template <> struct TypeName { constexpr static CArrayT< 'v', 'o', 'i', 'd'> name{}; }; 12 | template <> struct TypeName { constexpr static CArrayT< 'f', 'l', 'o','a', 't'> name{}; }; 13 | 14 | //const数组在匹配时发生了冲突,这里用SFINAE强制规定顺序 15 | template 16 | struct TypeName::value>::type> 17 | { 18 | constexpr static auto name = CArrayT< 'c', 'o', 'n', 's', 't', ' '>{}+TypeName::name; 19 | }; 20 | 21 | template 22 | struct TypeName 23 | { 24 | constexpr static auto name = CArrayT< 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 't', 'o', ' ' >{}+TypeName::name; 25 | }; 26 | template 27 | struct TypeName 28 | { 29 | constexpr static auto name = CArrayT< 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e', ' ', 'o', 'f', ' ' >{} +TypeName::name; 30 | }; 31 | template 32 | struct TypeName 33 | { 34 | constexpr static auto name = CArrayT<'r', '-', 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e', ' ', 'o', 'f', ' ' >{} +TypeName::name; 35 | }; 36 | 37 | template 38 | struct TypeName 39 | { 40 | constexpr static auto name = CArrayT<'a', 'r', 'r', 'a', 'y', '['>{} +ParseUInt::name + 41 | CArrayT<']', ' ', 'o', 'f', ' ' >{}+TypeName::name; 42 | }; 43 | 44 | template 45 | struct TypeNames; 46 | template 47 | struct TypeNames 48 | { 49 | constexpr static auto name = TypeName::name + CArrayT<','>{} +TypeNames::name; 50 | }; 51 | template 52 | struct TypeNames { constexpr static auto name = TypeName::name; }; 53 | template <> 54 | struct TypeNames<> { constexpr static ArrayT name{}; }; 55 | 56 | template 57 | struct TypeName 58 | { 59 | constexpr static auto name = CArrayT< 'f', 'u', 'n', 'c', 't', 'i', 'o', 'n', ' ', '('>{} +TypeNames::name + 60 | CArrayT< ')', ' ', 'r', 'e', 't', 'u', 'r', 'n', ' '>{}+TypeName::name; 61 | }; 62 | } -------------------------------------------------------------------------------- /test/SequenceContainer_Speed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "../Util.h" 10 | #include "../Deque.h" 11 | #include "../List.h" 12 | #include "../Vector.h" 13 | #include "../Algorithm.h" 14 | #include "../CircularQueue.h" 15 | #include "../ForwardList.h" 16 | 17 | using namespace std; 18 | using namespace ds; 19 | 20 | template 21 | constexpr int isListV = is_same_v> || is_same_v> || is_same_v> || is_same_v>; 22 | 23 | template 24 | void push_back_and_sort(const char *name) 25 | { 26 | Container seq; 27 | cout << name << endl; 28 | clock_t beg = clock(); 29 | for (int i = 0; i < 1e7; ++i) 30 | seq.push_back(rani(1, 1e9)); 31 | cout << "push_back: " << clock() - beg << endl; 32 | beg = clock(); 33 | if constexpr (isListV) 34 | seq.sort(); 35 | else 36 | std::sort(seq.begin(), seq.end()); 37 | cout << "sort: " << clock() - beg << endl; 38 | cout << "correct: " << boolalpha << is_sorted(seq.begin(), seq.end()) << endl; 39 | } 40 | 41 | template 42 | void push_front_and_sort(const char *name) 43 | { 44 | Container seq; 45 | cout << name << endl; 46 | clock_t beg = clock(); 47 | for (int i = 0; i < 1e7; ++i) 48 | seq.push_front(rani(1, 1e9)); 49 | cout << "push_front: " << clock() - beg << endl; 50 | beg = clock(); 51 | if constexpr (isListV) 52 | seq.sort(); 53 | else 54 | std::sort(seq.begin(), seq.end()); 55 | cout << "sort: " << clock() - beg << endl; 56 | cout << "correct: " << boolalpha << is_sorted(seq.begin(), seq.end()) << endl; 57 | } 58 | int main() 59 | { 60 | cout << "press to begin\n"; 61 | getchar(); 62 | push_back_and_sort>("stl vector"); 63 | push_back_and_sort>("stl deque"); 64 | push_back_and_sort>("stl list"); 65 | push_back_and_sort>("Vector"); 66 | push_back_and_sort>("Deque"); 67 | push_back_and_sort>("CircularQueue"); 68 | push_back_and_sort>("List"); 69 | 70 | push_front_and_sort>("stl deque"); 71 | push_front_and_sort>("stl list"); 72 | push_front_and_sort>("stl forward_list"); 73 | push_front_and_sort>("Deque"); 74 | push_front_and_sort>("CircularQueue"); 75 | push_front_and_sort>("List"); 76 | push_front_and_sort>("ForwardList"); 77 | } 78 | -------------------------------------------------------------------------------- /test/LuoguP3377LeftistTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../LeftistTree.h" 5 | template 6 | class LeftistTree 7 | { 8 | private: 9 | struct Node 10 | { 11 | K key; 12 | int dist = 0; 13 | Node *left = nullptr, *right = nullptr; 14 | Node(const K &key) :key(key) {} 15 | }; 16 | Node *root = nullptr; 17 | LeftistTree(Node *root) :root(root) {} 18 | static int dist(Node *x) { return x ? x->dist : -1; } 19 | static Node *merge(Node *x, Node *y) 20 | { 21 | if (!x) return y; 22 | if (!y) return x; 23 | if (x->key > y->key) //小根 24 | std::swap(x, y); 25 | x->right = merge(x->right, y); 26 | if (dist(x->right) > dist(x->left)) 27 | std::swap(x->left, x->right); 28 | x->dist = dist(x->right) + 1; 29 | return x; 30 | } 31 | public: 32 | LeftistTree() :root(nullptr) {} 33 | LeftistTree(const K &key) :root(new Node(key)) {} 34 | void merge(LeftistTree &rhs) 35 | { 36 | if (this!=&rhs) 37 | { 38 | root = merge(root, rhs.root); 39 | rhs.root = nullptr; 40 | } 41 | } 42 | //请自觉保证树非空 43 | const K &top()const { return root->key; } 44 | void pop() 45 | { 46 | root = merge(root->left, root->right); 47 | } 48 | void push(const K&key) 49 | { 50 | root = merge(root, new Node(key)); 51 | } 52 | bool empty()const { return !root; } 53 | }; 54 | int n, m; 55 | int nums[100010]; 56 | LeftistTree> heaps[100010]; 57 | //--------------------------------------------------------------- 58 | //简化的并查集 59 | int p[100010], rank[100010]; 60 | bool exist[100010]; 61 | void init(int n) 62 | { 63 | for (int i = 1; i <= n; ++i) 64 | p[i] = i; 65 | } 66 | int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); } 67 | //--------------------------------------------------------------- 68 | 69 | int main() 70 | { 71 | scanf("%d%d", &n, &m); 72 | init(n); 73 | for (int i = 1; i <= n; ++i) 74 | { 75 | scanf("%d", nums + i); 76 | heaps[i].push({ nums[i] ,i }); //当堆里有多个最小值时,优先删除原序列的靠前的 77 | exist[i] = true; 78 | } 79 | while (m--) 80 | { 81 | int opt, x, y; 82 | scanf("%d%d", &opt, &x); 83 | if (opt == 1) 84 | { 85 | scanf("%d", &y); 86 | if (exist[x]&&exist[y]) 87 | { 88 | int px = find(x), py = find(y); 89 | if (px==py) 90 | continue; 91 | p[py] = px; 92 | heaps[px].merge(heaps[py]); 93 | } 94 | } 95 | else 96 | { 97 | if (exist[x]) 98 | { 99 | int p = find(x); 100 | std::pair pr = heaps[p].top(); 101 | printf("%d\n", pr.first); 102 | exist[pr.second] = false; 103 | heaps[p].pop(); 104 | } 105 | else 106 | puts("-1"); 107 | } 108 | } 109 | return 0; 110 | } -------------------------------------------------------------------------------- /Util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using std::string; 10 | namespace ds 11 | { 12 | template 13 | std::ostream& operator<<(std::ostream &os,const std::pair &pr) 14 | { 15 | os << pr.first << ' ' << pr.second << ' '; 16 | return os; 17 | } 18 | template 19 | void print(K &&lst) 20 | { 21 | for (const auto &i : lst) 22 | std::cout << i << ' '; 23 | std::cout << std::endl; 24 | } 25 | 26 | struct GenIter 27 | { 28 | typedef std::random_access_iterator_tag iterator_category; 29 | typedef int value_type; 30 | typedef int difference_type; 31 | typedef int *pointer; 32 | typedef int &reference; 33 | int pos; 34 | GenIter(int pos = 0) : pos(pos) {} 35 | int operator*() const { return pos; } 36 | GenIter &operator+=(int offset) { return pos += offset, *this; } 37 | GenIter &operator-=(int offset) { return pos -= offset, *this; } 38 | GenIter &operator++() { return ++pos, *this; } 39 | GenIter operator++(int) { return pos++, *this; } 40 | GenIter &operator--() { return --pos, *this; } 41 | GenIter operator--(int) { return pos--, *this; } 42 | GenIter operator+(int offset) const { return pos + offset; } 43 | GenIter operator-(int offset) const { return pos - offset; } 44 | int operator-(GenIter rhs) const { return pos - rhs.pos; } 45 | bool operator!=(GenIter rhs) const { return pos != rhs.pos; } 46 | bool operator==(GenIter rhs) const { return pos == rhs.pos; } 47 | }; 48 | inline GenIter operator+(int offset, GenIter rhs) { return offset + rhs.pos; } 49 | 50 | 51 | inline uint32_t rawRani() 52 | { 53 | static unsigned seed = 19260817;// static_cast(time(nullptr)); 54 | auto xorshift32 = [&]()->uint32_t 55 | { 56 | /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */ 57 | uint32_t x = seed; 58 | x ^= x << 13; 59 | x ^= x >> 17; 60 | x ^= x << 5; 61 | return seed = x; 62 | }; 63 | return xorshift32(); 64 | } 65 | inline int rani(int l, int r) { return rawRani() % (r - l + 1) + l; } 66 | template 67 | const K &max(const K &lhs, const K &rhs) { return lhs < rhs ? rhs : lhs; } 68 | template 69 | const K &min(const K &lhs, const K &rhs) { return lhs < rhs ? lhs : rhs; } 70 | 71 | template 72 | struct Max 73 | { 74 | typedef K result_type; 75 | typedef K first_argument_type; 76 | typedef K second_argument_type; 77 | const K & operator()(const K &lhs, const K &rhs) const { return max(lhs, rhs); } 78 | }; 79 | 80 | template 81 | struct Min 82 | { 83 | typedef K result_type; 84 | typedef K first_argument_type; 85 | typedef K second_argument_type; 86 | const K & operator()(const K &lhs, const K &rhs) const { return min(lhs, rhs); } 87 | }; 88 | } -------------------------------------------------------------------------------- /toy/legacy/SegmentTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SegmentTreeUtil.h" 3 | 4 | namespace ds 5 | { 6 | //这是一颗抽象的线段树,任何满足区间加性质的类型&函数均可以用它实现 7 | //但是区间修改只支持区间加数 8 | //希望有一些更优雅的写法来支持区间乘/区间=/... 9 | //不过主要目的还是娱乐,谁会用这种东西做题呢? 10 | template 11 | class SegmentTree 12 | { 13 | private: 14 | Seg::Node root; 15 | typedef Seg::FuncTraits Function; 16 | static Function func; 17 | 18 | //节点的Left/Right是节点管辖的范围 19 | //查询的l/r是所需的范围 20 | template 21 | static K query(Seg::Node &x,int l,int r) 22 | { 23 | if (l <= Left && r >= Right) 24 | return x.key; 25 | pushDown(x); 26 | constexpr int mid = (Left + Right) / 2; 27 | 28 | K lres = Function::zero, rres = Function::zero; 29 | if (l <= mid) 30 | lres = query(x.left,l, r); 31 | if (r >= mid + 1) 32 | rres = query(x.right, l, r); 33 | return func(lres, rres); 34 | } 35 | template 36 | static K query(Seg::Node &x, int l, int r) { return x.key; } 37 | 38 | template 39 | constexpr static int lenOf(const Seg::Node &x) { return Right - Left + 1; } 40 | 41 | template 42 | static void addLabel(Seg::Node &x, const K &lb) { x.label += lb; } 43 | template 44 | static void addLabel(Seg::Node &x, const K &lb) { } 45 | template 46 | 47 | static void pushDown(Seg::Node &x) 48 | { 49 | if (x.label) 50 | { 51 | K lb = x.label; 52 | x.label = K(); 53 | x.left.key += Function::rangeSum(lb, lenOf(x.left)); 54 | x.right.key += Function::rangeSum(lb, lenOf(x.right)); 55 | addLabel(x.left, lb); 56 | addLabel(x.right, lb); 57 | } 58 | } 59 | template 60 | static void pushDown(Seg::Node &x) { } 61 | 62 | template 63 | static void rangeAdd(Seg::Node &x, int l, int r,const K &k) 64 | { 65 | if (l <= Left && r >= Right) 66 | { 67 | x.key += Function::rangeSum(k, lenOf(x)); 68 | x.label += k; 69 | return; 70 | } 71 | pushDown(x); 72 | constexpr int mid = (Left + Right) / 2; 73 | if (l <= mid) 74 | rangeAdd(x.left, l, r, k); 75 | if (r >= mid + 1) 76 | rangeAdd(x.right, l, r, k); 77 | x.key = func(x.left.key, x.right.key); 78 | } 79 | template 80 | static void rangeAdd(Seg::Node &x, int l, int r, const K &k) { x.key += k; } 81 | public: 82 | template 83 | SegmentTree(Iter it):root(it){} 84 | K query(int l, int r) { return query(root, l, r); } 85 | void rangeAdd(int l, int r, const K &k) { rangeAdd(root, l, r, k); } 86 | 87 | template 88 | void modify(int l,int r,const K &k) 89 | { 90 | 91 | } 92 | 93 | }; 94 | template 95 | typename SegmentTree::Function SegmentTree::func; 96 | } 97 | -------------------------------------------------------------------------------- /associative/TreeUtil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace ds 4 | { 5 | namespace TreeUtil 6 | { 7 | template 8 | LinkType extremeChild(LinkType x, LinkType nil, const int what) 9 | { 10 | while (x->ch[what] != nil) 11 | x = x->ch[what]; 12 | return x; 13 | } 14 | 15 | template 16 | LinkType nextNode(LinkType x, LinkType nil) 17 | { 18 | if (x->ch[1] != nil) 19 | return extremeChild(x->ch[1], nil, 0); 20 | while (x->p->ch[1] == x) 21 | x = x->p; 22 | return x->p;//x是最大节点时p为nil_ 23 | } 24 | 25 | template 26 | LinkType prevNode(LinkType x, LinkType nil, LinkType root) 27 | { 28 | if (x == nil) //end()的前一个 29 | return extremeChild(root, nil, 1); 30 | if (x->ch[0] != nil) 31 | return extremeChild(x->ch[0], nil, 1); 32 | while (x->p->ch[0] == x) 33 | x = x->p; 34 | return x->p;//x是最小节点时p为nil_ 35 | } 36 | 37 | template 38 | std::pair findNode(const KeyType &key, LinkType x, LinkType nil, Comp comp) //从x开始搜 39 | { 40 | LinkType p = nil; 41 | while (x != nil) 42 | { 43 | if (comp(x->key(), key)) 44 | p = x, x = x->ch[1]; 45 | else if (!comp(key, x->key())) 46 | return { x,p }; 47 | else 48 | p = x, x = x->ch[0]; 49 | } 50 | return { nullptr,p }; 51 | } 52 | template 53 | int lower(const KeyType &rend, LinkType root, LinkType nil, const bool afterEqual, Comp comp) 54 | { 55 | LinkType x = root; 56 | int cnt = 0; 57 | while (x != nil) 58 | { 59 | if (comp(x->key(), rend) || (afterEqual && !comp(rend, x->key()))) 60 | { 61 | cnt += x->ch[0]->sz + 1; 62 | x = x->ch[1]; 63 | } 64 | else 65 | x = x->ch[0]; 66 | } 67 | return cnt; 68 | } 69 | template 70 | LinkType kth(LinkType root, LinkType nil, int k) //k>size() or k<1时自动返回end() 71 | { 72 | LinkType x = root; 73 | while (x != nil) 74 | { 75 | LinkType l = x; 76 | l = l->ch[0]; 77 | if (l->sz + 1 == k) 78 | return x; 79 | if (l->sz + 1 < k) 80 | { 81 | k -= l->sz + 1; 82 | x = x->ch[1]; 83 | } 84 | else 85 | x = l; 86 | } 87 | return nil; 88 | } 89 | 90 | template 91 | void clear(LinkType x, LinkType nil) 92 | { 93 | if (!x || x == nil) 94 | return; 95 | clear(x->ch[0], nil); 96 | clear(x->ch[1], nil); 97 | delete x; 98 | } 99 | 100 | template 101 | void cpy(LinkType dest, LinkType destnil, const LinkType sour, const LinkType sournil) 102 | { 103 | for (int son = 0; son <= 1; ++son) 104 | if (sour->ch[son] != sournil) 105 | { 106 | dest->ch[son] = sour->ch[son]->clone(dest, destnil, destnil); //clone返回信息一样的节点 107 | cpy(dest->ch[son], destnil, sour->ch[son], sournil); 108 | } 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /toy/MemPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #ifdef _MSC_VER 4 | #include 5 | #endif 6 | 7 | namespace ds 8 | { 9 | //这个内存池能且仅能用于处理单个对象 10 | template 11 | class MemPool 12 | { 13 | #ifdef _MSC_VER 14 | static_assert(!std::is_same::value, 15 | "Fucking MSVC use MemPool on STACK to allocate std::_Container_proxy, which will crash the program"\ 16 | "There migth be something else like this, I can't guarantee"); 17 | #pragma warning("Don't use it on MSVC") 18 | #endif 19 | 20 | union Slot 21 | { 22 | K data; 23 | Slot *next; 24 | }; 25 | Slot *curBlock = nullptr, *freeSlot = nullptr;//freeSlot储存的是被deallocate释放的内存链表 26 | int pos = 1; 27 | 28 | public: 29 | typedef K value_type; 30 | typedef value_type *pointer; 31 | typedef value_type &reference; 32 | typedef const value_type *const_pointer; 33 | typedef const value_type &const_reference; 34 | typedef size_t size_type; 35 | typedef ptrdiff_t difference_type; 36 | template 37 | struct rebind { typedef MemPool other; }; 38 | 39 | pointer allocate(size_type = 1) 40 | { 41 | if (freeSlot != nullptr) 42 | { 43 | //这里表面上看起来同时使用了union的两个成员(既把freeSlot按照pointer解读,又读取了它的next) 44 | //但是实际上"按照pointer解读"并没有使用data,只是给了别人使用data的权力而已,data还需要别人来构造 45 | //这也就是allocate相当于malloc的原因,直接申请的内存是不可用的 46 | Slot *ret = freeSlot; 47 | freeSlot = freeSlot->next; 48 | return reinterpret_cast(ret); 49 | } 50 | if (pos == BlockSize || curBlock == nullptr) 51 | { 52 | Slot *tmp = curBlock; 53 | curBlock = reinterpret_cast(malloc(BlockSize * sizeof(Slot))); 54 | curBlock->next = tmp; //虽曰next,其实指向的是之前申请的内存 55 | pos = 1; 56 | } 57 | //从1开始使用内存,不能破坏curBlock内存放的next(这就是所谓的overhead) 58 | return reinterpret_cast(curBlock + pos++); //一个block中内存是连续的 59 | } 60 | template 61 | void construct(pointer p,Args&& ...args) 62 | { 63 | new(p) value_type(std::forward(args)...); 64 | } 65 | 66 | void deallocate(pointer p, size_type) 67 | { 68 | if (p) 69 | { 70 | Slot *tmp = reinterpret_cast(p); 71 | tmp->next = freeSlot; //虽曰next,其实指向的是之前返回的内存 72 | freeSlot = tmp; 73 | } 74 | } 75 | static void destroy(pointer p) 76 | { 77 | p->~value_type(); 78 | } 79 | MemPool() noexcept { } 80 | //表面上看起来有各种构造,其实并不做任何事 81 | template 82 | MemPool(const MemPool&) noexcept { } 83 | 84 | //出于某种我无法理解的原因,微软的编译器会在stl容器的构造函数中利用allocator来构造一个_Container_proxy 85 | //而且那个allocator是在函数内创建的,很快就析构了。如果执行析构函数那个proxy就会被释放掉,从而挂掉 86 | 87 | ~MemPool() 88 | { 89 | while (curBlock) 90 | { 91 | Slot *nxt = curBlock->next; 92 | free(curBlock); 93 | curBlock = nxt; 94 | } 95 | } 96 | }; 97 | template 98 | bool operator==(const MemPool &, const MemPool &) { return true; } 99 | template 100 | bool operator!=(const MemPool &, const MemPool &) { return false; } 101 | 102 | } -------------------------------------------------------------------------------- /toy/SharedPtr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace ds 6 | { 7 | //侵入式的智能指针 8 | //只要使用它的类包含一个 _cnt_ 成员并且保证不修改它即可 9 | namespace detail 10 | { 11 | template ()._cnt_)> 12 | constexpr bool hasCnt(int) { return true; } 13 | template 14 | constexpr bool hasCnt(float) { return true; } 15 | } 16 | 17 | struct DefaultDelete 18 | { 19 | template 20 | void operator()(K *&p) const 21 | { 22 | delete p; 23 | p = nullptr; 24 | } 25 | }; 26 | 27 | struct ArrayDelete 28 | { 29 | template 30 | void operator()(K *&p) const 31 | { 32 | delete[]p; 33 | p = nullptr; 34 | } 35 | }; 36 | //没有stl那么多顾虑 37 | //每个SharedPtr配一个Del太浪费了,不支持 38 | template 39 | struct SharedPtr 40 | { 41 | static_assert(detail::hasCnt(0), "K must has field _cnt_"); 42 | static_assert(std::is_class::value, 43 | "SharedPtr only support struct with operator() as its deleter \n function and lambda are not accepted"); 44 | K *ptr; 45 | const static Delete Del; 46 | void tryDel() 47 | { 48 | if (ptr && --(ptr->_cnt_) == 0) 49 | Del(ptr); 50 | } 51 | //下面用模板写了拷贝构造/拷贝赋值 52 | //但是这 不会 覆盖掉编译器合成的构造/拷贝赋值 53 | //从而编译器合成的函数比模板函数的优先级更高,执行了合成的版本,导致错误 54 | //所以必须显式提供这两个函数(移动构造/赋值则不需要,因为此时编译器不会合成它们) 55 | SharedPtr(const SharedPtr &rhs) { ++(ptr = rhs.ptr)->_cnt_; } 56 | SharedPtr &operator=(const SharedPtr &rhs) 57 | { 58 | ++rhs.ptr->_cnt_; 59 | tryDel(); 60 | ptr = rhs.ptr; 61 | return *this; 62 | } 63 | SharedPtr(K *ptr = nullptr) :ptr(ptr) { if (ptr) ptr->_cnt_ = 1; } 64 | template 65 | void swap(SharedPtr &rhs) noexcept { std::swap(ptr, rhs.ptr); } 66 | template 67 | SharedPtr(const SharedPtr &rhs) { ++(ptr = rhs.ptr)->_cnt_; } 68 | template 69 | SharedPtr &operator=(const SharedPtr &rhs) 70 | { 71 | ++rhs.ptr->_cnt_; //先+再-,无需判断自赋值 72 | tryDel(); 73 | ptr = rhs.ptr; 74 | return *this; 75 | } 76 | template 77 | SharedPtr(SharedPtr &&rhs) noexcept { ptr = rhs.ptr, rhs.ptr = nullptr; } 78 | template 79 | SharedPtr& operator=(SharedPtr &&rhs) noexcept 80 | { 81 | SharedPtr tmp(std::move(rhs)); 82 | swap(tmp); 83 | return *this; 84 | } 85 | 86 | //注意区分const sharedptr 与 sharedptr 87 | //后者才是真正的const type *,所以const版本的重载仍返回无const的*和& 88 | K &operator*() { return *ptr; } 89 | K &operator*() const { return *ptr; } 90 | K *operator->() { return ptr; } 91 | K *operator->() const { return ptr; } 92 | K *get() const { return ptr; } 93 | void reset(K *ptr = nullptr) { tryDel(); this->ptr = ptr; } 94 | explicit operator bool() const { return ptr != nullptr; } 95 | K &operator[](int x) { return ptr[x]; } //stl没有提供这个 96 | ~SharedPtr() { tryDel(); } 97 | }; 98 | template 99 | const Delete SharedPtr::Del{}; 100 | template 101 | SharedPtr makeShared(Args&& ...args) 102 | { 103 | return new K(std::forward(args)...); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /heap/MinMaxHeap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Vector.h" 3 | namespace ds 4 | { 5 | template 6 | class MinMaxHeap 7 | { 8 | std::vector vec; 9 | //isMaxLevel指的是它比它的所有孩子大 10 | static bool isMaxLevel(int pos) 11 | { 12 | int lg = 0; 13 | for (int sum = 0, i = 1; sum < pos; sum += (i <<= 1)) 14 | ++lg; 15 | return lg & 1; 16 | } 17 | int checkSon(int pos, bool maxLevel, int size) 18 | { 19 | int son = (pos << 1) + 1; 20 | if (maxLevel) //pos是max level,它的孩子应该比他大,选出较大的孩子 21 | { 22 | son += (son + 1 < size && vec[son] < vec[son + 1]); 23 | return (son < size && vec[pos] < vec[son]) ? son : 0; 24 | } 25 | son += (son + 1 < size && vec[son + 1] < vec[son]); 26 | return (son < size && vec[son] < vec[pos]) ? son : 0; 27 | } 28 | int checkGSon(int pos, bool maxLevel, int size) 29 | { 30 | const int gson[4] = { (pos << 2) + 3,(pos << 2) + 4,(pos << 2) + 5,(pos << 2) + 6 }; 31 | int ret = pos; 32 | if (maxLevel) //pos是max level,它的孙子应该比他大,选出最大的孙子 33 | { 34 | for (int i = 0; i < 4 && gson[i] < size; ++i) 35 | if (vec[ret] < vec[gson[i]]) 36 | ret = gson[i]; 37 | return ret == pos ? 0 : ret; 38 | } 39 | for (int i = 0; i < 4 && gson[i] < size; ++i) 40 | if (vec[gson[i]] < vec[ret]) 41 | ret = gson[i]; 42 | return ret == pos ? 0 : ret; 43 | } 44 | void popFix(int pos) 45 | { 46 | const bool maxLevel = isMaxLevel(pos); 47 | const int size = vec.size(); 48 | int nxt; 49 | while (true) 50 | { 51 | if ((nxt = checkSon(pos, maxLevel, size)) != 0) //优先满足孩子,但是满足了孩子之后不能更新nxt 52 | std::swap(vec[nxt], vec[pos]); 53 | if ((nxt = checkGSon(pos, maxLevel, size)) != 0) //检查孙子的前提是已经满足了孩子,这时可以更新nxt 54 | std::swap(vec[nxt], vec[pos]), pos = nxt; 55 | else break; 56 | } 57 | } 58 | public: 59 | void push(const T &val) 60 | { 61 | vec.push_back(val); 62 | int x = vec.size() - 1, p = (x - 1) >> 1, g = (p - 1) >> 1, nxt; 63 | bool maxLevel = isMaxLevel(x); 64 | while (x) 65 | { 66 | if (maxLevel) 67 | { 68 | if (vec[x] < vec[p]) //它是max,意味着它的父亲是min,需要比他小 69 | std::swap(vec[p], vec[x]), nxt = p, maxLevel ^= 1; 70 | else if (p && vec[g] < vec[x]) //它的祖父也是max,若果它比祖父大则需要更新祖父 71 | std::swap(vec[g], vec[x]), nxt = g; 72 | else break; 73 | } 74 | else 75 | { 76 | if (vec[p] < vec[x]) 77 | std::swap(vec[p], vec[x]), nxt = p, maxLevel ^= 1; 78 | else if (p && vec[x] < vec[g]) 79 | std::swap(vec[g], vec[x]), nxt = g; 80 | else break; 81 | } 82 | x = nxt, p = (x - 1) >> 1, g = (p - 1) >> 1; 83 | } 84 | } 85 | void popMin() 86 | { 87 | std::swap(vec.front(), vec.back()); 88 | vec.pop_back(); 89 | popFix(0); 90 | } 91 | void popMax() 92 | { 93 | int pos = &max() - &vec[0]; 94 | std::swap(vec[pos], vec.back()); 95 | vec.pop_back(); 96 | popFix(pos); 97 | } 98 | const T &min() const noexcept { return vec[0]; } 99 | const T &max() const noexcept 100 | { 101 | if (vec.size() == 1) 102 | return vec[0]; 103 | if (vec.size() == 2 || vec[2] < vec[1]) 104 | return vec[1]; 105 | return vec[2]; 106 | } 107 | int size() const { return vec.size(); } 108 | bool empty() const { return vec.empty(); } 109 | }; 110 | } -------------------------------------------------------------------------------- /toy/Complexity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Matrix.h" 3 | #include 4 | #include 5 | #include "Profiler.h" 6 | 7 | namespace ds 8 | { 9 | struct Complexity 10 | { 11 | enum O { lgn, sqrtn, n, nlgn, n2, n3 }; 12 | struct Result { double k, b, R2; }; 13 | static std::array, 6> table; 14 | template 15 | static Result calc(const Matrix &input , Func f) 16 | { 17 | //不管什么输入,反正用double处理 18 | Matrix A; 19 | Matrix B; 20 | for (int i = 0; i 40 | static Result calc(const Matrix &input,decltype(O::n) type) 41 | { 42 | //注意参数不是int!尤其是在上面还有个模板函数的情况下,给int那enum就会被模板匹配到 43 | return calc(input, table[type]); 44 | } 45 | template 46 | static Result autoCalc(Func f, const std::array &n, int type) 47 | { 48 | Matrix input; 49 | for (int i = 0; i 59 | static Result autoCalc(Func f, Prep p,const std::array &n, int type) 60 | { 61 | Matrix input; 62 | for (int i = 0; i < N; ++i) 63 | { 64 | p(n[i]); 65 | Profiler prof; 66 | f(n[i]); 67 | input[i][1] = prof.reset(); 68 | input[i][0] = n[i]; 69 | } 70 | return calc(input, table[type]); 71 | } 72 | }; 73 | std::array, 6> Complexity::table = 74 | { 75 | [](double d) {return log2(d); }, 76 | [](double d) {return sqrt(d); }, 77 | [](double d) {return d; }, 78 | [](double d) {return d * log2(d); }, 79 | [](double d) {return d * d; }, 80 | [](double d) {return d * d * d; } 81 | }; 82 | } 83 | /*demo 84 | const int maxn = 5e6; 85 | int a[maxn]; 86 | int main() 87 | { 88 | for (int i = 0; i < maxn; ++i) 89 | a[i] = i; 90 | auto f1 = [](int n) {std::sort(a, a + n); }; 91 | auto f2 = [](int n) {ds::radixSort(a, a + n); }; 92 | auto p = [](int n) {random_shuffle(a, a + n); }; 93 | const int start = 1e5, step = 1e5; 94 | array arr; 95 | arr[0] = start; 96 | for (int i = 1; i < arr.size(); ++i) 97 | arr[i] = arr[i - 1] + step; 98 | auto res = Complexity::autoCalc(f1, p, arr, Complexity::nlgn); 99 | cout << res.k << ' ' << res.b << ' ' << res.R2 << endl; 100 | res = Complexity::autoCalc(f2, p, arr, Complexity::n); 101 | cout << res.k << ' ' << res.b << ' ' << res.R2 << endl; 102 | //运行,得到结果发现b<0,这可能是动态内存申请导致的 103 | getchar(); 104 | } 105 | 106 | */ -------------------------------------------------------------------------------- /toy/IntrusiveList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ds 5 | { 6 | /*template 失败的尝试 7 | struct ArrayTag //node 本身就是int ? or ? 8 | { 9 | 10 | };*/ 11 | struct PointerTag {}; 12 | 13 | template 14 | struct IntrusiveListNode; 15 | 16 | template<> 17 | struct IntrusiveListNode 18 | { 19 | typedef IntrusiveListNode* pointer; 20 | pointer prev; 21 | pointer next; 22 | pointer operator->() { return this; } //按道理来说应该是node.left/right,然而由于.操作符不可重载,会给数组下标版的带来麻烦,所以同意用-> 23 | operator pointer() { return this; } 24 | bool operator==(const IntrusiveListNode &rhs) const { return prev == rhs.prev&&next == rhs.next; } 25 | bool operator!=(const IntrusiveListNode &rhs) const { return !(operator==(rhs)); } 26 | }; 27 | 28 | template 29 | class IntrusiveList 30 | { 31 | #define listEntry(ptr) (K*)((char *)ptr - offsetOf(K,node)) 32 | #define offsetOf(TYPE, member) ((size_t)& ((TYPE *)0)->member) 33 | //其实这东西在C语言的库里面就有...还要改一下名字免得重了 34 | typedef decltype(K().node) Node; 35 | typedef typename Node::pointer pointer; 36 | K nil; 37 | int size = 0; 38 | //auto deref(pointer ptr)->decltype(Node::deref(0)) { return Node::deref(ptr); } //仅仅是为了不用每次都写Node:: 39 | public: 40 | IntrusiveList() { nil.node->next = nil.node->prev = nil.node; } 41 | void push_back(K &key) //显然右值之类的东西不能用于侵入式数据结构 42 | { 43 | key.node->next = nil.node, key.node->prev = nil.node->prev; 44 | nil.node->prev->next = key.node, nil.node->prev = key.node; 45 | } 46 | void push_front(K &key) 47 | { 48 | key.node->prev = nil.node, key.node->next = nil.node->next; 49 | nil.node->next->prev = key.node, nil.node->next = key.node; 50 | } 51 | void erase(K &key) 52 | { 53 | assert(key.node != nil); 54 | key.node->next->prev = key.node->prev; 55 | key.node->prev->next = key.node->next; 56 | } 57 | static void insert(K &where, K &key) { insert(where.node, key); } 58 | static void insert(Node node, K &key) //insert before 59 | { 60 | key.node->next = node, key.node->prev = node->prev; 61 | node->prev->next = key.node, node->prev = key.node; 62 | } 63 | static K& entryOf(Node node) { return *listEntry(pointer(node)); } 64 | static K& entryOf(pointer ptr) { return *listEntry(ptr); } 65 | static K& inc(K &key) { return key = entryOf(key.node->next); } 66 | static K& dec(K &key) { return key = entryOf(key.node->prev); } 67 | static K& next(const K &key) { return entryOf(key.node->next); } 68 | static K& prev(const K &key) { return entryOf(key.node->prev); } 69 | K &front() { return *listEntry(nil.node->next); } 70 | K &back() { return *listEntry(nil.node->prev); } 71 | const K &front() const { return *listEntry(nil.node->next); } 72 | const K &back() const { return *listEntry(nil.node->prev); } 73 | K &begin() { return front(); } 74 | K &end() { return nil; } 75 | const K &begin() const { return front(); } 76 | const K &end() const { return nil; } 77 | }; 78 | 79 | } 80 | 81 | //demo 82 | /*struct ListedInt 83 | { 84 | int val; 85 | bool operator!=(const ListedInt &rhs) const { return node != rhs.node; } 86 | int& operator*() { return val; } 87 | ListedInt& operator++() { return IntrusiveList::inc(*this); } 88 | IntrusiveListNode node; 89 | }; 90 | ostream& operator<<(ostream &os,const ListedInt &x) 91 | { 92 | os << x.val; 93 | return os; 94 | } 95 | ListedInt arr[1000]; 96 | IntrusiveList list; */ -------------------------------------------------------------------------------- /heap/FibHeap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "List.h" 3 | #include 4 | #include 5 | 6 | namespace ds 7 | { 8 | //我实在懒得定义类型了....反正斐波那契堆也不需要和标准库交互 9 | //注意template template parameter的语法,默认模板参数被忽略,必须手动指出 10 | //保证内存泄漏,没有拷贝控制,谁爱用谁用 11 | template> typename Container = List> 12 | class FibHeap 13 | { 14 | public: 15 | struct Node 16 | { 17 | private: 18 | K key; 19 | Node *p = nullptr; 20 | typename Container::iterator self; 21 | Container childs; 22 | bool marked = false; 23 | explicit Node(const K & key) :key(key) {} 24 | public: 25 | friend FibHeap; 26 | int degree()const { return childs.size(); } 27 | const K& getKey() const { return key; } 28 | }; 29 | typedef typename Container::iterator iterator; 30 | Node* push(const K &key) 31 | { 32 | Node *x = new Node(key); 33 | iterator it = roots.insert(roots.end(), x); 34 | x->self = it; //不写在一行,因为x既被修改也被取用,未定义行为 35 | if (!min || key < min->key) 36 | min = x; 37 | return x; 38 | } 39 | void decreaseKey(Node *x, const K &key) 40 | { 41 | x->key = key; 42 | Node *y = x->p; 43 | if (y && x->key < y->key) 44 | { 45 | cut(x); 46 | cascadingCut(y); 47 | } 48 | if (x->key < min->key) 49 | min = x; 50 | } 51 | void delNode(Node *x) 52 | { 53 | decreaseKey(x, std::numeric_limits::min()); 54 | pop(); 55 | } 56 | const K &top() const { return min->getKey(); } 57 | void pop() 58 | { 59 | for (auto it : min->childs) 60 | it->p = nullptr; 61 | roots.splice(roots.end(), min->childs); 62 | roots.erase(min->self); 63 | popFix(); 64 | } 65 | void merge(FibHeap &src) 66 | { 67 | roots.splice(roots.end(),src.roots); 68 | if (!min || (src.min&&src.min->key < min->key)) 69 | min = src.min; 70 | src.min = nullptr; 71 | } 72 | bool empty()const{return roots.empty();} 73 | private: 74 | Node *min = nullptr; 75 | Container roots; 76 | void cut(Node *x) //x被切掉并放到根 77 | { 78 | roots.splice(roots.end(), x->p->childs, x->self); 79 | x->p = nullptr; 80 | x->marked = false; 81 | } 82 | void cascadingCut(Node *y) 83 | { 84 | while (y->p) 85 | { 86 | if (!y->marked) //节点减值在cut(x)之后紧接一步cascadingCut(x->p),如果x->没有标记那么这里标记上 87 | { 88 | y->marked = true; 89 | break; 90 | } 91 | Node *tmp = y->p; 92 | cut(y); //cur把y->p置为nullptr 93 | y = tmp; 94 | } 95 | } 96 | Node *aux[32]; 97 | void popFix() 98 | { 99 | memset(aux, 0, sizeof(aux)); 100 | for (auto it = roots.begin(); it != roots.end();) 101 | { 102 | Node *x = *it; 103 | ++it; 104 | while (Node *y = aux[x->degree()]) 105 | { 106 | aux[x->degree()] = nullptr; 107 | if (y->key < x->key) 108 | link(y, x), x = y; 109 | else 110 | link(x, y); 111 | } 112 | aux[x->degree()] = x; 113 | } 114 | roots.clear(); 115 | min = nullptr; 116 | for (int i = 0; i < 32; ++i) 117 | if (aux[i]) 118 | { 119 | iterator it= roots.insert(roots.end(), aux[i]); 120 | aux[i]->self = it; 121 | if (!min || aux[i]->key < min->key) 122 | min = aux[i]; 123 | } 124 | } 125 | void link(Node *x, Node *y) //把y从根链表中移除并且加入x的孩子 126 | { 127 | y->marked = false; 128 | y->p = x; 129 | x->childs.splice(x->childs.end(), roots, y->self); 130 | } 131 | }; 132 | } 133 | -------------------------------------------------------------------------------- /toy/KDTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | namespace ds 8 | { 9 | template 10 | class KDTree 11 | { 12 | const std::array dimen; 13 | std::vector pts; 14 | std::vector split; //必须把每一次分割的维度保存下来才能查询 15 | std::vector tags; 16 | 17 | void build(int l, int r) //[0,n) indexed 18 | { 19 | if (l >= r) return; 20 | int mid = (l + r) >> 1; 21 | //求出每一维的方差 22 | split[mid] = 0; 23 | double var = 0.0; 24 | for (int d = 0; d < Dimen; ++d)//找到方差最大的那一维,split[mid] = argmax(var,var+Dimen) 25 | { 26 | double ave = 0.0, tmpvar = 0.0; 27 | for (int i = l; i < r; i++) 28 | ave += dimen[d](pts[i]); 29 | ave /= r - l; 30 | for (int i = l; i < r; ++i) 31 | tmpvar += pow(dimen[d](pts[i]) - ave, 2); //方差没有除元素个数,因为没有必要 32 | if (tmpvar > var) 33 | var = tmpvar, split[mid] = d; 34 | } 35 | //找到中间点 36 | std::nth_element(pts.begin() + l, pts.begin() + mid, pts.begin() + r, 37 | [=](const K &lhs, const K &rhs) 38 | {return dimen[split[mid]](lhs) < dimen[split[mid]](rhs); }); 39 | 40 | build(l, mid); 41 | build(mid + 1, r); 42 | } 43 | 44 | struct Result 45 | { 46 | const K &point; 47 | double distance2; 48 | }; 49 | double ans; 50 | int index; 51 | int timeTag = 0; 52 | //ans和index只由query使用;放在函数参数里面传太累了 53 | void query(const K &pt,int l, int r) 54 | { 55 | if (l >= r) return; 56 | int mid = (l + r) >> 1; 57 | //求出目标点pt到现在的根节点mid的欧几里得距离,没有开根号,因为没有必要 58 | double dis = 0.0; 59 | for (int d = 0; d < Dimen; d++) 60 | dis += pow(dimen[d](pts[mid]) - dimen[d](pt), 2); 61 | if (tags[mid] != timeTag && dis < ans) //更新最近距离 62 | ans = dis, index = mid; 63 | //计算pt到[分裂平面]的距离 64 | //注意到分裂平面是垂直与被分割的维度的坐标轴的,所以点到平面的距离只需要一个坐标差 65 | double currOfPt = dimen[split[mid]](pt), currOfMid = dimen[split[mid]](pts[mid]); 66 | double r2 = pow(currOfMid - currOfPt, 2); 67 | if (currOfPt < currOfMid) //对子区间进行查询,类似二叉树 68 | { 69 | query(pt, l, mid); 70 | //在某个子树查询完之后,以该点为圆心,目前找到的最小距离为半径画"球" 71 | //看是否和分裂区间的"平面"相交(r2 <= ans),要是相交的话,最近点可能还在另一个子树上,所以还要再查询另一个子树 72 | if (r2 <= ans) 73 | query(pt, mid + 1, r); 74 | } 75 | else 76 | { 77 | query(pt, mid + 1, r); 78 | if (r2 <= ans) 79 | query(pt, l, mid); 80 | } 81 | } 82 | public: 83 | KDTree(decltype(dimen) dimen, const std::vector &pts) 84 | :dimen(dimen), pts(pts),split(pts.size()),tags(split.size()) 85 | { 86 | build(0, pts.size()); 87 | } 88 | std::vector knn(const K &pt,int k) 89 | { 90 | std::vector ret; 91 | ++timeTag; 92 | while (k--) 93 | { 94 | ans = DBL_MAX, index = -1; 95 | query(pt, 0, pts.size()); 96 | tags[index] = timeTag; 97 | ret.push_back({ pts[index] ,ans }); 98 | } 99 | return ret; 100 | } 101 | }; 102 | } 103 | /* demo 104 | array, 2> arr = 105 | { 106 | [](const P&p) {return p.x; }, 107 | [](const P&p) {return p.y; }, 108 | }; 109 | const int maxn = 200000; 110 | vector

input(maxn); 111 | for (int i = 0; i < input.size(); ++i) 112 | input[i] = { rani(1,maxn),rani(1,maxn) }; 113 | KDTree kd(arr, input); 114 | auto knn = kd.knn({ maxn / 2,maxn / 2 }, 20); 115 | for (auto &p : knn) 116 | cout << p.point.x << ' ' << p.point.y << ' ' << sqrt(p.distance2) << endl; 117 | getchar(); 118 | */ -------------------------------------------------------------------------------- /toy/PersistentTreap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Util.h" 3 | #include 4 | 5 | namespace ds 6 | { 7 | //数组式非旋Treap 8 | //只提供multi_set的功能,而且删除元素时只删一个(这与multi_set不一样) 9 | class PersintentTreap 10 | { 11 | const static int maxn = 5e5 + 10; 12 | struct Node 13 | { 14 | int key, sz, ch[2]; 15 | unsigned pri; 16 | } tr[maxn * 50] = {}; 17 | int roots[maxn] = {}, tsize = 0; 18 | 19 | void update(int x) 20 | { 21 | tr[x].sz = tr[tr[x].ch[0]].sz + 1 + tr[tr[x].ch[1]].sz; 22 | } 23 | //实际上split操作普通二叉树也可以做 24 | //但是merge必须依赖于pri 25 | //把树tr[now]分裂成两个部分x和y 26 | //其中x的key全部<=k,y的key全部>=k 27 | void split(int now, int k, int &x, int &y) 28 | { 29 | if (!now) 30 | x = y = 0; 31 | else 32 | { 33 | if (tr[now].key <= k) 34 | { 35 | x = ++tsize; 36 | tr[x] = tr[now]; 37 | split(tr[x].ch[1], k, tr[x].ch[1], y); 38 | update(x); 39 | } 40 | else 41 | { 42 | y = ++tsize; 43 | tr[y] = tr[now]; 44 | split(tr[y].ch[0], k, x, tr[y].ch[0]); 45 | update(y); 46 | } 47 | } 48 | } 49 | 50 | //x中的所有key都小于y中的所有key 51 | int merge(int x, int y) 52 | { 53 | if (!x || !y) 54 | return x + y; 55 | if (tr[x].pri > tr[y].pri) 56 | { 57 | int p = ++tsize; 58 | tr[p] = tr[x]; 59 | tr[p].ch[1] = merge(tr[p].ch[1], y); 60 | update(p); 61 | return p; 62 | } 63 | else 64 | { 65 | int p = ++tsize; 66 | tr[p] = tr[y]; 67 | tr[p].ch[0] = merge(x, tr[p].ch[0]); 68 | update(p); 69 | return p; 70 | } 71 | } 72 | int newNode(int k) 73 | { 74 | tr[++tsize].key = k; 75 | tr[tsize].sz = 1; 76 | tr[tsize].pri = rawRani(); 77 | return tsize; 78 | } 79 | public: 80 | void insert(int nver,int ver, int k) 81 | { 82 | int x, y; 83 | split(roots[ver], k, x, y); 84 | roots[nver] = merge(merge(x, newNode(k)), y); 85 | } 86 | 87 | void erase(int nver, int ver, int k) 88 | { 89 | int x, y, z; 90 | split(roots[ver], k, x, z); //x中全部<=k 91 | split(x, k - 1, x, y); //y中全部=k 92 | y = merge(tr[y].ch[0], tr[y].ch[1]); //确保只删除了一个元素 93 | roots[nver] = merge(merge(x, y), z); 94 | } 95 | int kth(int nver, int ver, int k) 96 | { 97 | //唯一一个和普通平衡树一样的 98 | roots[nver] = roots[ver]; 99 | int x = roots[ver]; 100 | while (x) 101 | { 102 | int tmp = tr[tr[x].ch[0]].sz + 1; 103 | if (tmp < k) 104 | k -= tmp, x = tr[x].ch[1]; 105 | else if (k == tmp) 106 | return tr[x].key; 107 | else 108 | x = tr[x].ch[0]; 109 | } 110 | } 111 | int rank(int nver, int ver, int k) 112 | { 113 | roots[nver] = roots[ver]; 114 | int x, y; 115 | split(roots[ver], k - 1, x, y); 116 | int ret = tr[x].sz + 1; 117 | roots[ver] = merge(x, y); 118 | return ret; 119 | } 120 | int pre(int nver, int ver, int k) 121 | { 122 | roots[nver] = roots[ver]; 123 | int x, y; 124 | split(roots[ver], k - 1, x, y); 125 | int tmp = x; 126 | while (tr[x].ch[1]) //<=k-1的最大值 127 | x = tr[x].ch[1]; 128 | int ret = tr[x].key; 129 | roots[ver] = merge(tmp, y); 130 | return ret; 131 | } 132 | int nxt(int nver, int ver, int k) 133 | { 134 | roots[nver] = roots[ver]; 135 | int x, y; 136 | split(roots[ver], k, x, y); 137 | int tmp = y; 138 | while (tr[y].ch[0]) //>k的最小值 139 | y = tr[y].ch[0]; 140 | int ret = tr[y].key; 141 | roots[ver] = merge(x, tmp); 142 | return ret; 143 | } 144 | }; 145 | } 146 | -------------------------------------------------------------------------------- /toy/TimSort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Algorithm.h" 3 | #include 4 | namespace 5 | { 6 | template> 7 | class TimSort 8 | { 9 | private: 10 | typedef typename std::iterator_traits::value_type value_type; 11 | const Iter first, last; 12 | Comp comp; 13 | const static int MIN_MERGE = 32; 14 | int stackSize = 0; 15 | int *runFirst, *runLen; 16 | value_type *aux; 17 | //一个run指一段连续不降的或者连续严格降的子串 18 | //countRunAndMakeAscending找出以_first开头,不超过last-1的最长run;并且如果是连续降,顺便反转之 19 | int countRunAndMakeAscending(Iter _first) //似乎可以去掉第二个参数? 20 | { 21 | int lo = 0, runHi = 1, hi = last - _first; 22 | if (_first + 1 == last) 23 | return 1; 24 | if (comp(_first[runHi++], _first[lo]))//下降 25 | { 26 | while (runHi < hi && comp(_first[runHi], _first[runHi - 1])) 27 | runHi++; 28 | ds::reverse(_first, _first + runHi); 29 | } 30 | else //不降 31 | while (runHi < hi && !comp(_first[runHi], _first[runHi - 1])) 32 | runHi++; 33 | return runHi - lo; 34 | } 35 | static int minRunLength(int n) 36 | { 37 | int r = 0; 38 | while (n >= MIN_MERGE) 39 | { 40 | r |= n & 1; 41 | n >>= 1; 42 | } 43 | return n + r; 44 | } 45 | void insertSort(Iter _first, Iter _last, int div = 0) //[_first,_first + _div)已经排好序了 46 | { 47 | Iter cur = _first + div; 48 | while (cur != _last) 49 | { 50 | Iter tmp = cur++; 51 | auto value = std::move(*tmp); 52 | while (tmp != _first&&comp(value, *(tmp - 1))) 53 | *tmp = std::move(*(tmp - 1)), --tmp; 54 | *tmp = std::move(value); 55 | } 56 | } 57 | void pushRun(int _first, int len) 58 | { 59 | runFirst[stackSize] = _first; 60 | runLen[stackSize] = len; 61 | ++stackSize; 62 | } 63 | void mergeAt(int n) //把栈中的下标n和n+1归并,n <= stackSize-2 64 | { 65 | //assert(runFirst[n + 1] == runFirst[n] + runLen[n]) 66 | runLen[n] += runLen[n + 1]; 67 | if (n == stackSize - 3) //挪动一位 68 | runFirst[n + 1] = runFirst[n + 2], runLen[n + 1] = runLen[n + 2]; 69 | --stackSize; 70 | ds::merge(first + runFirst[n], first + runFirst[n + 1], first + runFirst[n + 1] + runLen[n + 1], comp, aux); 71 | } 72 | void mergeCollapse() 73 | { 74 | while (stackSize > 1) 75 | { 76 | int n = stackSize - 2; 77 | if (n > 0 && runLen[n - 1] <= runLen[n] + runLen[n + 1]) 78 | { 79 | if (runLen[n - 1] < runLen[n + 1]) 80 | --n; 81 | mergeAt(n); 82 | } 83 | else if (runLen[n] <= runLen[n + 1]) 84 | mergeAt(n); 85 | else break; 86 | } 87 | } 88 | public: 89 | TimSort(Iter first, Iter last, Comp comp = Comp()) :first(first), last(last), comp(comp) 90 | { 91 | const int len = last - first; 92 | const int stackLen = len < 120 ? 5 : 93 | len < 1542 ? 10 : 94 | len < 119151 ? 24 : 49; 95 | runFirst = new int[stackLen], runLen = new int[stackLen]; 96 | aux = new value_type[len]; 97 | } 98 | void sort() 99 | { 100 | int len = last - first, lo = 0, hi = len; 101 | if (len <= 1) return; 102 | if (len < MIN_MERGE) 103 | { 104 | insertSort(first, last, 0); 105 | return; 106 | } 107 | const int minRun = minRunLength(len); 108 | do 109 | { 110 | int curLen = countRunAndMakeAscending(first + lo); 111 | if (curLen < minRun) 112 | { 113 | const int force = len <= minRun ? len : minRun;//避免越界 114 | insertSort(first + lo, first + lo + force, curLen); 115 | curLen = force; 116 | } 117 | pushRun(lo, curLen); 118 | mergeCollapse(); 119 | lo += curLen; 120 | len -= curLen; 121 | } while (len != 0); 122 | while (stackSize > 1) 123 | mergeAt(stackSize - 2); 124 | } 125 | ~TimSort() 126 | { 127 | delete runFirst; 128 | delete runLen; 129 | delete aux; 130 | } 131 | }; 132 | } 133 | -------------------------------------------------------------------------------- /toy/DynamicSegTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Algorithm.h" 3 | namespace ds 4 | { 5 | //动态顺序统计量 6 | //插入,删除,rank : O(lgU) 7 | //前驱,后继,kth : O(lg^2(U)) 8 | //空间 : O(n*lgU) (对比普通权值线段树 : O(U)) 9 | template 10 | class DynamicSegTree; 11 | 12 | template 13 | class DynamicSegTree 14 | { 15 | struct Node 16 | { 17 | int l, r; 18 | int size; 19 | }; 20 | static Node tree[MaxSize]; 21 | static int treeSize; 22 | int root = 0; 23 | const int minKey, maxKey; 24 | static void erase(int rt,int l,int r,int key) 25 | { 26 | if (l > r || !rt) return; 27 | int mid = (l + r) >> 1; 28 | if (l < r) 29 | { 30 | key <= mid ? erase(tree[rt].l, l, mid, key) : erase(tree[rt].r, mid + 1, r, key); 31 | tree[rt].size = tree[tree[rt].l].size + tree[tree[rt].r].size; 32 | } 33 | else if (tree[rt].size) 34 | --tree[rt].size; 35 | } 36 | //求出 r) return tree[rt].size; 41 | while (rt) 42 | { 43 | int mid = (l + r) >> 1; 44 | if (key <= mid) 45 | rt = tree[rt].l, r = mid; 46 | else 47 | rk += tree[tree[rt].l].size, rt = tree[rt].r, l = mid + 1; 48 | } 49 | return rk; 50 | } 51 | public: 52 | DynamicSegTree(int minKey, int maxKey) :minKey(minKey), maxKey(maxKey) { } 53 | int size() const { return tree[root].size; } 54 | int count(int key) const 55 | { 56 | int l = minKey, r = maxKey, rt = root; 57 | while (tree[rt].size) 58 | { 59 | int mid = (l + r) >> 1; 60 | if (l == r && l == key) 61 | return tree[rt].size; 62 | if (key <= mid) 63 | rt = tree[rt].l, r = mid; 64 | else 65 | rt = tree[rt].r, l = mid + 1; 66 | } 67 | return 0; 68 | } 69 | bool exist(int key) const { return count(key); } 70 | void insert(int key) 71 | { 72 | int l = minKey, r = maxKey, *rt = &root; 73 | while (l <= r) 74 | { 75 | if (!*rt) 76 | *rt = ++treeSize; 77 | ++tree[*rt].size; 78 | if (l == r) 79 | break; 80 | int mid = (l + r) >> 1; 81 | if (key <= mid) 82 | rt = &tree[*rt].l, r = mid; 83 | else 84 | rt = &tree[*rt].r, l = mid + 1; 85 | } 86 | } 87 | void erase(int key) const 88 | { 89 | //erase不存在的节点可能需要回溯,但是没有记录p,所以不能回溯 90 | //所以erase还是采用递归的方法 91 | erase(root, minKey, maxKey, key); 92 | } 93 | int rank(int key) const 94 | { 95 | return lower(root, minKey, maxKey, key) + 1; 96 | } 97 | int kth(int k) const 98 | { 99 | //当k<1时返回最小值,k>size()时返回最大值 100 | int l = minKey, r = maxKey, rt = root; 101 | while (tree[rt].size) 102 | { 103 | if (l == r) 104 | return l; 105 | int mid = (l + r) >> 1; 106 | if (tree[tree[rt].l].size < k) 107 | k -= tree[tree[rt].l].size, rt = tree[rt].r, l = mid + 1; 108 | else 109 | rt = tree[rt].l, r = mid; 110 | } 111 | return -1; 112 | } 113 | int findPrev(int key) const 114 | { 115 | int rk = rank(key) - 1; 116 | return rk < 1 ? -1 : kth(rk); 117 | } 118 | int findNext(int key) const 119 | { 120 | int rk = rank(key) + count(key); 121 | return rk > size() ? -1 : kth(rk); 122 | } 123 | int findMin() const { return findNext(minKey - 1); } 124 | int findMax() const { return findPrev(maxKey + 1); } 125 | }; 126 | template 127 | typename DynamicSegTree::Node DynamicSegTree::tree[MaxSize]; 128 | template 129 | int DynamicSegTree::treeSize = 0; 130 | 131 | // template 132 | // class DynamicSegTree 133 | // { 134 | // static struct Node 135 | // { 136 | // int l, r; 137 | // int size; 138 | // } tree[MaxSize]; 139 | // }; 140 | // 141 | // template 142 | // class DynamicSegTree 143 | // { 144 | // 145 | // }; 146 | } -------------------------------------------------------------------------------- /test/Map_Speed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../Map.h" 8 | #include "../Algorithm.h" 9 | #include "../BTree.h" 10 | #include "../AVL.h" 11 | #include "../Splay.h" 12 | #include "../Util.h" 13 | #include "../HashMap.h" 14 | #include "../SkipList.h" 15 | #include "../Treap.h" 16 | #include "../vEBTree.h" 17 | #include "../BITTree.h" 18 | #include "../RBTreeWithoutSize.h" 19 | using namespace std; 20 | using namespace ds; 21 | 22 | const int maxn = 5e6; 23 | int input[maxn]; 24 | 25 | template 26 | void test(const char *name) 27 | { 28 | M m; 29 | cout << name << endl; 30 | clock_t beg[3] = { clock() }; 31 | for (int i = 0; i < maxn; ++i) 32 | m.insert({ input[i] ,0 }); 33 | cout << "insert :" << -beg[0] + (beg[1] = clock()) << endl; 34 | for (int i = 0; i < maxn; ++i) 35 | m.find(input[i]); 36 | cout << "find :" << -beg[1] + (beg[2] = clock()) << endl; 37 | for (int i = 0; i < maxn; ++i) 38 | m.erase(input[i]); 39 | cout << "erase :" << -beg[2] + clock() << endl; 40 | cout << "all :" << clock() - beg[0] << endl; 41 | } 42 | 43 | int main() 44 | { 45 | for (int i = 0; i < maxn; ++i) 46 | input[i] = i; 47 | random_shuffle(input, input + maxn); 48 | cout << "press to begin\n"; 49 | getchar(); 50 | 51 | test>("stl map"); 52 | test>("BTree"); 53 | test>("RBTree"); 54 | test, RBTreeWithoutSize>>("RBTree without size"); 55 | test, Treap>>("Treap"); 56 | test, Splay>>("Splay"); 57 | test, AVL>>("AVL"); 58 | test>("SkipList"); 59 | } 60 | //veb & bit 61 | /*const int maxn = 3e6; 62 | int input[maxn]; 63 | clock_t beg[4] = { clock() }; 64 | //vEBTree<23> veb; 65 | BITTree veb; 66 | int main() 67 | { 68 | for (int i = 0; i < maxn; ++i) 69 | input[i] = i + 1; 70 | random_shuffle(input, input + maxn); 71 | 72 | beg[1] = clock(); 73 | for (int i = 0; i < maxn; ++i) 74 | veb.insert(input[i]); 75 | cout << "insert :" << -beg[1] + (beg[2] = clock()) << "\n"; 76 | for (int i = 0; i < maxn; ++i) 77 | bool b = veb.exist(input[i]); 78 | cout << "find :" << -beg[2] + (beg[3] = clock()) << "\n"; 79 | for (int i = 0; i < maxn; ++i) 80 | veb.erase(input[i]); 81 | cout << "erase :" << -beg[3] + clock() << "\n"; 82 | cout << "all :" << clock() - beg[1] << "\n"; 83 | getchar(); 84 | }*/ 85 | 86 | // kth 87 | /*int main() 88 | { 89 | const int maxn = 3e5; 90 | Map m; 91 | Map, AVL> avlm; 92 | BTree bt; 93 | for (int i = 0; i < maxn; ++i) 94 | { 95 | int ran = rani(1, maxn); 96 | m.insert(ran, 0); 97 | avlm.insert(ran, 0); 98 | bt.insert(ran, 0); 99 | } 100 | 101 | for (int i = 0; i < maxn; ++i) 102 | { 103 | int ran = rani(1, maxn); 104 | m.erase(ran); 105 | avlm.erase(ran); 106 | bt.erase(ran); 107 | } 108 | freopen("mp.txt", "w", stdout); 109 | for (int i = 1; i <= m.size(); ++i) 110 | cout << m.kth(i)->first << ' '; 111 | freopen("avlmp.txt", "w", stdout); 112 | for (int i = 1; i <= avlm.size(); ++i) 113 | cout << avlm.kth(i)->first << ' '; 114 | freopen("bt.txt", "w", stdout); 115 | for (int i = 1; i <= bt.size(); ++i) 116 | cout << bt.kth(i)->first << ' '; 117 | }*/ 118 | 119 | /*内存泄漏检验 120 | { 121 | Map m; 122 | for (int i = 0; i < 1e5; ++i) 123 | m.insert(i, 2 * i + 1); 124 | { 125 | cout << "hit to construct m1" << endl; 126 | getchar(); 127 | auto m1 = m; 128 | cout << "hit to construct m2" << endl; 129 | getchar(); 130 | auto m2 = std::move(m1); 131 | cout << "hit to construct m3" << endl; 132 | getchar(); 133 | auto m3(m2); 134 | cout << "hit to destruct m123" << endl; 135 | getchar(); 136 | } 137 | 138 | 139 | getchar(); 140 | }*/ 141 | -------------------------------------------------------------------------------- /associative/SkipList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Util.h" 4 | #include 5 | namespace ds 6 | { 7 | //不与Map兼容 8 | template 9 | class SkipList 10 | { 11 | private: 12 | const static int MaxLevel = 16; 13 | const static int P = 4 - 1; //用于随机数取模,从而决定随机level;为了取模效率,固定P=2^k-1 14 | typedef typename Traits::KeyType KeyType; 15 | typedef typename Traits::ValueType ValueType; 16 | typedef typename Traits::KeyCompare KeyCompare; 17 | KeyCompare comp; 18 | public: 19 | struct Node 20 | { 21 | ValueType value; 22 | Node *next[MaxLevel] = { nullptr }; 23 | const KeyType &key()const { return Traits::KeyOf(value); } 24 | explicit Node(const ValueType &value) :value(value) {} 25 | Node() = default; 26 | }; 27 | private: 28 | Node *nil = nullptr; //nil装很多指针,但是不装数据;最小数据在nil->next[0]中 29 | int level = 1; 30 | static int randomLevel() 31 | { 32 | int nlevel = 1; 33 | while (nlevel < MaxLevel && (rawRani() & P) == 0) 34 | ++nlevel; 35 | return nlevel; 36 | } 37 | Node *prev[MaxLevel]; 38 | Node* findNode(const KeyType &key) 39 | { 40 | Node *x = nil; 41 | for (int i = level - 1; i >= 0; --i) 42 | { 43 | while (x->next[i] && comp(x->next[i]->key(), key)) 44 | x = x->next[i]; 45 | prev[i] = x; 46 | } 47 | return x->next[0]; 48 | } 49 | public: 50 | SkipList(KeyCompare comp) :comp(comp), nil(new Node){} //注意顺序,顺序是由nil和head的定义顺序决定的 51 | Node *insert(const ValueType &value) 52 | { 53 | Node *x = findNode(Traits::KeyOf(value)); 54 | if (x && !comp(Traits::KeyOf(value), x->key())) 55 | return x; 56 | const int nlevel = randomLevel(); 57 | if (nlevel > level) 58 | { 59 | for (int i = level; i < nlevel; ++i) //多出来的level与nil连接在一起 60 | prev[i] = nil; 61 | level = nlevel; 62 | } 63 | x = new Node(value); 64 | for (int i = 0; i < nlevel; ++i) 65 | { 66 | x->next[i] = prev[i]->next[i]; //类似链表插入 67 | prev[i]->next[i] = x; 68 | } 69 | return x; 70 | } 71 | void erase(const KeyType &key) 72 | { 73 | Node *x = findNode(key); 74 | if (x && !comp(key, x->key())) 75 | { 76 | for (int i = 0; i < level && prev[i]; ++i) 77 | if (prev[i]->next[i]!=x) break; 78 | else prev[i]->next[i] = x->next[i]; 79 | delete x; 80 | while (level > 1 && !(nil->next[level - 1])) 81 | --level; 82 | } 83 | } 84 | ValueType *find(const KeyType &key) const 85 | { 86 | Node *x = nil; 87 | for (int i = level - 1; i >= 0; --i) 88 | while (x->next[i] && comp(x->next[i]->key(), key)) 89 | x = x->next[i]; 90 | x = x->next[0]; 91 | if (x && !comp(key, x->key())) 92 | return &(x->value); 93 | return nullptr; 94 | } 95 | template 96 | void walk(Pred pred) 97 | { 98 | for (Node *x = nil->next[0]; x; x = x->next[0]) 99 | pred(x->value); 100 | } 101 | template 102 | auto walk(Pred pred, Reduce reduce) ->decltype(reduce(pred(nil->value), pred(nil->value))) 103 | { 104 | typedef decltype(reduce(pred(nil->value), pred(nil->value))) ReturnType; 105 | ReturnType ret = ReturnType(); //必须自己保证零元,比如乘法,walk并不对默认构造出来的0负责 106 | for (Node *x = nil; x; x = x->next[0]) 107 | ret = reduce(ret, pred(x->value)); 108 | return ret; 109 | } 110 | }; 111 | template 112 | struct SkipListMapTraits 113 | { 114 | typedef K KeyType; 115 | typedef std::pair ValueType; 116 | typedef Comp KeyCompare; 117 | static const KeyType &KeyOf(const ValueType &value) { return value.first; } 118 | }; 119 | template> 120 | class SkipListMap : public SkipList> 121 | { 122 | public: 123 | SkipListMap(Comp comp = Comp()) :SkipList>(comp) {} 124 | }; 125 | template 126 | struct SkipListSetTraits 127 | { 128 | typedef K KeyType; 129 | typedef K ValueType; 130 | typedef Comp KeyCompare; 131 | static const KeyType &KeyOf(const ValueType &value) { return value; } 132 | }; 133 | template> 134 | class SkipListSet : public SkipList> 135 | { 136 | public: 137 | SkipListSet(Comp comp = Comp()) :SkipList>(comp) {} 138 | }; 139 | } -------------------------------------------------------------------------------- /integer/BitSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ds 5 | { 6 | template 7 | class BitSet 8 | { 9 | using Int = unsigned long long; 10 | const static int IntSize = sizeof(Int) * 8; 11 | const static int Size = Bit / IntSize + (Bit % IntSize != 0); 12 | Int bits[Size] = { 0 }; 13 | void trim() { bits[Size - 1] &= (1ull << Bit % IntSize) - 1; } 14 | public: 15 | BitSet() = default; 16 | BitSet(Int init) :BitSet() { bits[0] = init; } 17 | explicit operator std::string() const 18 | { 19 | std::string ret(Bit, '\0'); 20 | for (int i = 0; i < Bit; ++i) 21 | ret[i] = at(i) + '0'; 22 | return ret; 23 | } 24 | int count() const 25 | { 26 | const char table[] = 27 | "\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4" 28 | "\1\2\2\3\2\3\3\4\2\3\3\4\3\4\4\5" 29 | "\1\2\2\3\2\3\3\4\2\3\3\4\3\4\4\5" 30 | "\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6" 31 | "\1\2\2\3\2\3\3\4\2\3\3\4\3\4\4\5" 32 | "\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6" 33 | "\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6" 34 | "\3\4\4\5\4\5\5\6\4\5\5\6\5\6\6\7" 35 | "\1\2\2\3\2\3\3\4\2\3\3\4\3\4\4\5" 36 | "\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6" 37 | "\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6" 38 | "\3\4\4\5\4\5\5\6\4\5\5\6\5\6\6\7" 39 | "\2\3\3\4\3\4\4\5\3\4\4\5\4\5\5\6" 40 | "\3\4\4\5\4\5\5\6\4\5\5\6\5\6\6\7" 41 | "\3\4\4\5\4\5\5\6\4\5\5\6\5\6\6\7" 42 | "\4\5\5\6\5\6\6\7\5\6\6\7\6\7\7\x8"; 43 | int sum = 0; 44 | for (auto cur = reinterpret_cast(bits), end = cur + sizeof(bits) 45 | ; cur != end; ++cur) 46 | sum += table[*cur]; 47 | return sum; 48 | } 49 | bool at(int pos) const 50 | { 51 | const int byte = pos / IntSize, bit = pos % IntSize; 52 | return bits[byte] & 1ull << bit; 53 | } 54 | void set(int pos, bool val = true) 55 | { 56 | const int byte = pos / IntSize, bit = pos % IntSize; 57 | val ? bits[byte] |= 1ull << bit : bits[byte] &= ~1ull << bit; 58 | } 59 | friend BitSet operator<<(BitSet lhs, int rhs) { return lhs <<= rhs; } 60 | friend BitSet operator>>(BitSet lhs, int rhs) { return lhs >>= rhs; } 61 | friend BitSet operator&(BitSet lhs, int rhs) { return lhs &= rhs; } 62 | friend BitSet operator|(BitSet lhs, int rhs) { return lhs |= rhs; } 63 | friend BitSet operator^(BitSet lhs, int rhs) { return lhs ^= rhs; } 64 | void flip() 65 | { 66 | for (int i = 0; i < Size; ++i) 67 | bits[i] = ~bits[i]; 68 | trim(); 69 | } 70 | BitSet operator~() const 71 | { 72 | BitSet ret(*this); 73 | for (int i = 0; i < Size; ++i) 74 | ret.bits[i] = ~ret.bits[i]; 75 | ret.trim(); 76 | return ret; 77 | } 78 | BitSet &operator<<=(int shift) 79 | { 80 | const int wordShift = shift / IntSize; 81 | if (wordShift != 0) 82 | for (int pos = Size - 1; pos >= 0; --pos) 83 | bits[pos] = wordShift <= pos ? bits[pos - wordShift] : 0; 84 | if ((shift %= IntSize) != 0) 85 | { 86 | for (int pos = Size - 1; pos > 0; --pos) 87 | bits[pos] = (bits[pos] << shift) | (bits[pos - 1] >> (IntSize - shift)); 88 | bits[0] <<= shift; 89 | } 90 | return *this; 91 | } 92 | BitSet &operator>>=(int shift) 93 | { 94 | const int wordShift = shift / IntSize; 95 | if (wordShift != 0) 96 | for (int pos = 0; pos < Size; ++pos) 97 | bits[pos] = wordShift < Size - pos ? bits[pos + wordShift] : 0; 98 | if ((shift %= IntSize) != 0) 99 | { 100 | for (int pos = 0; pos < Size - 1; ++pos) 101 | bits[pos] = (bits[pos] >> shift) | (bits[pos + 1] << (IntSize - shift)); 102 | bits[Size - 1] >>= shift; 103 | } 104 | return *this; 105 | } 106 | BitSet &operator&=(const BitSet &rhs) 107 | { 108 | for (int i = 0; i < Size; ++i) 109 | bits[i] &= rhs.bits[i]; 110 | trim(); 111 | return *this; 112 | } 113 | BitSet &operator|=(const BitSet &rhs) 114 | { 115 | for (int i = 0; i < Size; ++i) 116 | bits[i] |= rhs.bits[i]; 117 | trim(); 118 | return *this; 119 | } 120 | BitSet &operator^=(const BitSet &rhs) 121 | { 122 | for (int i = 0; i < Size; ++i) 123 | bits[i] ^= rhs.bits[i]; 124 | trim(); 125 | return *this; 126 | } 127 | struct BitRef 128 | { 129 | BitSet *self; 130 | int pos; 131 | operator bool() const { return self->at(pos); } 132 | BitRef &operator=(bool b) { return self->set(pos, b), *this; } 133 | }; 134 | BitRef operator[](int pos) { return { this,pos }; } 135 | bool operator[](int pos) const { return at(pos); } 136 | }; 137 | } -------------------------------------------------------------------------------- /toy/Trie.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace ds 4 | { 5 | struct NullType 6 | { 7 | }; 8 | //可以当multiset用,但是不能当multimap用,懒得搞了 9 | template > 10 | class Trie 11 | { 12 | public: 13 | typedef Container Seq; 14 | typedef MappedType V; 15 | typedef ElementType K; 16 | typedef int ToIndex(K); 17 | 18 | private: 19 | struct Node 20 | { 21 | int sz = 0; //counting the node AND its childs 22 | int cnt = 0; //only self 23 | V val; 24 | Node *kids[AlphabetSize] = { nullptr }; 25 | Node *p = nullptr; 26 | Node(Node *p = nullptr) : p(p) {} 27 | }; 28 | Node *root_; 29 | ToIndex *toIndex_; 30 | void clear(Node *x) 31 | { 32 | if (!x) 33 | return; 34 | for (int i = 0; i < AlphabetSize; ++i) 35 | clear(x->kids[i]); 36 | if (x != root_) 37 | delete x; 38 | else 39 | { 40 | x->sz = x->cnt = 0; 41 | for (int i = 0; i < AlphabetSize; ++i) 42 | x->kids[i] = nullptr; 43 | } 44 | } 45 | void cpy(Node *dest, const Node *sour) 46 | { 47 | dest->sz = sour->sz, dest->cnt = sour->cnt, dest->val = sour->val; 48 | for (int i = 0; i < AlphabetSize; ++i) 49 | if (sour->kids[i]) 50 | { 51 | dest->kids[i] = new Node(dest); 52 | cpy(dest->kids[i], sour->kids[i]); 53 | } 54 | } 55 | Node *findNode(const Seq &key) const 56 | { 57 | Node *x = root_; 58 | int d = 0, len = key.size(); 59 | while (d < len) 60 | { 61 | int index = toIndex_(key[d]); 62 | if (!x->kids[index]) 63 | return nullptr; 64 | x = x->kids[index]; 65 | ++d; 66 | } 67 | return x; 68 | } 69 | 70 | public: 71 | Trie(ToIndex toIndex) : root_(new Node), toIndex_(toIndex) {} 72 | void put(const Seq &key, const V &val = V()) 73 | { 74 | Node *x = root_, *y = x; 75 | int d = 0, len = key.size(); 76 | while (d < len) 77 | { 78 | int index = toIndex_(key[d]); 79 | if (!(x->kids[index])) 80 | x->kids[index] = new Node(x); 81 | y = x; 82 | ++y->sz; 83 | x = x->kids[index]; 84 | ++d; 85 | } 86 | x->val = val, ++x->cnt, ++x->sz; 87 | x->p = y; 88 | } 89 | V *find(const Seq &key) const 90 | { 91 | Node *x = findNode(key); 92 | if (!x || !x->cnt) //找到了链上的某个节点,但是该节点没有值 93 | return nullptr; 94 | return &(x->val); 95 | } 96 | 97 | void del(const Seq &key) 98 | { 99 | Node *x = root_; 100 | int d = 0, len = key.size(); 101 | while (d < len) 102 | { 103 | int index = toIndex_(key[d]); 104 | --x->sz; 105 | if (!x->kids[index]) 106 | { 107 | while (x) 108 | ++x->sz, x = x->p; 109 | return; 110 | } 111 | x = x->kids[index]; 112 | ++d; 113 | } 114 | Node *y = x; 115 | if (!y->cnt) //key只是已经存在的某个串的一部分,并没有真的找到 116 | { 117 | while (x) 118 | ++x->sz, x = x->p; 119 | return; 120 | } 121 | --y->cnt, --y->sz; 122 | d = len - 1; 123 | while (y != root_ && !y->sz) 124 | { 125 | x = x->p; 126 | delete y; 127 | x->kids[toIndex_(key[d--])] = nullptr; 128 | y = x; 129 | } 130 | } 131 | int size() const { return root_->sz; } 132 | int size(const Seq &key) const //以key为前缀的串的数量 133 | { 134 | Node *x = findNode(key); 135 | if (!x) 136 | return 0; 137 | return x->sz; 138 | } 139 | 140 | int count(const Seq &key) const 141 | { 142 | Node *x = findNode(key); 143 | if (!x) 144 | return 0; 145 | return x->cnt; 146 | } 147 | void clear() { clear(root_); } 148 | void swap(Trie &rhs) noexcept 149 | { 150 | std::swap(root_, rhs.root_); 151 | std::swap(toIndex_, rhs.toIndex_); 152 | } 153 | Trie &operator=(Trie rhs) 154 | { 155 | swap(*this, rhs); //释放自身的资源由rhs的析构函数来做 156 | return *this; 157 | } 158 | Trie(const Trie &rhs) : root_(new Node), toIndex_(rhs.toIndex_) 159 | { 160 | cpy(root_, rhs.root_); 161 | } 162 | Trie &operator=(Trie &&rhs) noexcept 163 | { 164 | if (this != &rhs) 165 | { 166 | ~Trie(); //释放自身的资源 167 | root_ = rhs.root_; 168 | toIndex_ = rhs.toIndex_; 169 | rhs.root_ = nullptr; 170 | } 171 | return *this; 172 | } 173 | Trie(Trie &&rhs) noexcept 174 | { 175 | root_ = rhs.root_; 176 | toIndex_ = rhs.toIndex_; 177 | rhs.root_ = nullptr; 178 | } 179 | ~Trie() 180 | { 181 | clear(root_); 182 | delete root_; 183 | } 184 | }; 185 | } 186 | -------------------------------------------------------------------------------- /toy/WBT.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Util.h" 3 | 4 | namespace ds { 5 | using i32 = int; 6 | using u32 = unsigned; 7 | struct WBT { 8 | constexpr static u32 N = 5e5 + 10; 9 | constexpr static u32 D = 3, G = 2; 10 | 11 | struct Node { 12 | i32 key; 13 | u32 sz, l, r; 14 | } pool[N * 32]; 15 | u32 top = 0, root[N]; 16 | 17 | u32 alloc(i32 key, u32 l, u32 r) { 18 | u32 ret = ++top; 19 | pool[ret].key = key; 20 | pool[ret].sz = pool[l].sz + pool[r].sz + 1; 21 | pool[ret].l = l; 22 | pool[ret].r = r; 23 | return ret; 24 | } 25 | 26 | bool is_balanced(u32 x, u32 y) { 27 | return D * (pool[x].sz + 1) >= (pool[y].sz + 1); 28 | } 29 | 30 | bool is_single(u32 x, u32 y) { 31 | return (pool[x].sz + 1) < G * (pool[y].sz + 1); 32 | } 33 | 34 | u32 single_l(i32 key, u32 l, u32 r) { 35 | return alloc(pool[r].key, alloc(key, l, pool[r].l), pool[r].r); 36 | } 37 | 38 | u32 double_l(i32 key, u32 l, u32 r) { 39 | return alloc(pool[pool[r].l].key, alloc(key, l, pool[pool[r].l].l), alloc(pool[r].key, pool[pool[r].l].r, pool[r].r)); 40 | } 41 | 42 | u32 single_r(i32 key, u32 l, u32 r) { 43 | return alloc(pool[l].key, pool[l].l, alloc(key, pool[l].r, r)); 44 | } 45 | 46 | u32 double_r(i32 key, u32 l, u32 r) { 47 | return alloc(pool[pool[l].r].key, alloc(pool[l].key, pool[l].l, pool[pool[l].r].l), alloc(key, pool[pool[l].r].r, r)); 48 | } 49 | 50 | u32 balance_l(i32 key, u32 l, u32 r) { 51 | if (is_balanced(l, r)) { return alloc(key, l, r); } 52 | return is_single(pool[r].l, pool[r].r) ? single_l(key, l, r) : double_l(key, l, r); 53 | } 54 | 55 | u32 balance_r(i32 key, u32 l, u32 r) { 56 | if (is_balanced(r, l)) { return alloc(key, l, r); } 57 | return is_single(pool[l].r, pool[l].l) ? single_r(key, l, r) : double_r(key, l, r); 58 | } 59 | 60 | u32 insert(u32 x, i32 key) { 61 | if (x == 0) { 62 | u32 ret = ++top; 63 | pool[ret].key = key; 64 | pool[ret].sz = 1; 65 | return ret; 66 | } 67 | if (key < pool[x].key) { return balance_r(pool[x].key, insert(pool[x].l, key), pool[x].r); } 68 | return balance_l(pool[x].key, pool[x].l, insert(pool[x].r, key)); 69 | } 70 | 71 | // return (root after del max, max value) 72 | std::pair pop_max(u32 x) { 73 | if (pool[x].r == 0) { return {pool[x].l, pool[x].key}; } 74 | auto pr = pop_max(pool[x].r); 75 | return {balance_r(pool[x].key, pool[x].l, pr.first), pr.second}; 76 | } 77 | 78 | std::pair pop_min(u32 x) { 79 | if (pool[x].l == 0) { return {pool[x].r, pool[x].key}; } 80 | auto pr = pop_min(pool[x].l); 81 | return {balance_l(pool[x].key, pr.first, pool[x].r), pr.second}; 82 | } 83 | 84 | u32 remove(u32 x, i32 key) { 85 | if (x == 0) { return 0; } 86 | if (key < pool[x].key) { return balance_l(pool[x].key, remove(pool[x].l, key), pool[x].r); } 87 | if (pool[x].key < key) { return balance_r(pool[x].key, pool[x].l, remove(pool[x].r, key)); } 88 | u32 l = pool[x].l, r = pool[x].r; 89 | if (l == 0 || r == 0) { return l + r; } 90 | if (pool[l].sz > pool[r].sz) { 91 | auto pr = pop_max(l); 92 | return balance_l(pr.second, pr.first, r); 93 | } else { 94 | auto pr = pop_min(r); 95 | return balance_r(pr.second, l, pr.first); 96 | } 97 | } 98 | 99 | i32 nxt(u32 x, i32 key) { 100 | u32 p = 0; 101 | while (x) { 102 | if (key < pool[x].key) { 103 | p = x, x = pool[x].l; 104 | } else { 105 | x = pool[x].r; 106 | } 107 | } 108 | return p ? pool[p].key : 2147483647; 109 | } 110 | 111 | i32 pre(u32 x, i32 key) { 112 | u32 p = 0; 113 | while (x) { 114 | if (pool[x].key < key) { 115 | p = x, x = pool[x].r; 116 | } else { 117 | x = pool[x].l; 118 | } 119 | } 120 | return p ? pool[p].key : -2147483647; 121 | } 122 | 123 | u32 lt(u32 x, i32 key) { 124 | u32 ret = 0; 125 | while (x) { 126 | if (pool[x].key < key) { 127 | ret += 1 + pool[pool[x].l].sz, x = pool[x].r; 128 | } else { 129 | x = pool[x].l; 130 | } 131 | } 132 | return ret; 133 | } 134 | 135 | i32 kth(u32 x, u32 k) { 136 | while (true) { 137 | if (k <= pool[pool[x].l].sz) { 138 | x = pool[x].l; 139 | } else if (k == pool[pool[x].l].sz + 1) { 140 | return pool[x].key; 141 | } else { 142 | k -= pool[pool[x].l].sz + 1, x = pool[x].r; 143 | } 144 | } 145 | } 146 | }; 147 | } // namespace ds -------------------------------------------------------------------------------- /test/LuoguP3371Dijkstra-FibHeap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../FibHeap.h" 6 | 7 | template> typename Container> 8 | class FibHeap 9 | { 10 | public: 11 | struct Node 12 | { 13 | private: 14 | K key; 15 | Node *p = nullptr; 16 | typename Container::iterator self; 17 | Container childs; 18 | bool marked = false; 19 | explicit Node(const K & key) :key(key) {} 20 | public: 21 | friend FibHeap; 22 | int degree()const { return childs.size(); } 23 | const K& getKey() const { return key; } 24 | }; 25 | typedef typename Container::iterator iterator; 26 | Node* push(const K &key) 27 | { 28 | Node *x = new Node(key); 29 | iterator it = roots.insert(roots.end(), x); 30 | x->self = it; //不写在一行,因为x既被修改也被取用,未定义行为 31 | if (!min || key < min->key) 32 | min = x; 33 | return x; 34 | } 35 | void decreaseKey(Node *x, const K &key) 36 | { 37 | x->key = key; 38 | Node *y = x->p; 39 | if (y && x->key < y->key) 40 | { 41 | cut(x); 42 | cascadingCut(y); 43 | } 44 | if (x->key < min->key) 45 | min = x; 46 | } 47 | const K &top() const { return min->getKey(); } 48 | void pop() 49 | { 50 | for (auto it : min->childs) 51 | it->p = nullptr; 52 | roots.splice(roots.end(), min->childs); 53 | roots.erase(min->self); 54 | popFix(); 55 | } 56 | bool empty()const { return roots.empty(); } 57 | private: 58 | Node *min = nullptr; 59 | Container roots; 60 | void cut(Node *x) //x被切掉并放到根 61 | { 62 | roots.splice(roots.end(), x->p->childs, x->self); 63 | x->p = nullptr; 64 | x->marked = false; 65 | } 66 | void cascadingCut(Node *y) 67 | { 68 | while (y->p) 69 | { 70 | if (!y->marked) //节点减值在cut(x)之后紧接一步cascadingCut(x->p),如果x->没有标记那么这里标记上 71 | { 72 | y->marked = true; 73 | break; 74 | } 75 | Node *tmp = y->p; 76 | cut(y); //cur把y->p置为nullptr 77 | y = tmp; 78 | } 79 | } 80 | Node *aux[32]; 81 | void popFix() 82 | { 83 | memset(aux, 0, sizeof(aux)); 84 | for (auto it = roots.begin(); it != roots.end();) 85 | { 86 | Node *x = *it; 87 | ++it; 88 | while (Node *y = aux[x->degree()]) 89 | { 90 | aux[x->degree()] = nullptr; 91 | if (y->key < x->key) 92 | link(y, x), x = y; 93 | else 94 | link(x, y); 95 | } 96 | aux[x->degree()] = x; 97 | } 98 | roots.clear(); 99 | min = nullptr; 100 | for (int i = 0; i < 32; ++i) 101 | if (aux[i]) 102 | { 103 | iterator it = roots.insert(roots.end(), aux[i]); 104 | aux[i]->self = it; 105 | if (!min || aux[i]->key < min->key) 106 | min = aux[i]; 107 | } 108 | } 109 | void link(Node *x, Node *y) //把y从根链表中移除并且加入x的孩子 110 | { 111 | y->marked = false; 112 | y->p = x; 113 | x->childs.splice(x->childs.end(), roots, y->self); 114 | } 115 | }; 116 | 117 | typedef std::vector vi; 118 | typedef std::pair pii; 119 | const int inf = 0x3f3f3f3f; 120 | const int maxn = 1e4 + 10; 121 | 122 | int d[maxn]; 123 | int v_cnt, e_cnt; 124 | struct Edge 125 | { 126 | int to, w; 127 | Edge(int _to, double _w) : to(_to), w(_w) {} 128 | }; 129 | typedef std::vector ve; 130 | ve edges[maxn]; 131 | 132 | typedef typename FibHeap::Node Node; 133 | Node *nodes[maxn]; 134 | void dijkstra(int s) 135 | { 136 | memset(d, 0x3f, sizeof(d)); 137 | FibHeap fib; 138 | for (int i = 1; i <= v_cnt; ++i) 139 | if (i != s) 140 | nodes[i] = fib.push({ inf ,i }); 141 | else 142 | nodes[i] = fib.push({ 0,i }); 143 | d[s] = 0; 144 | while (!fib.empty()) 145 | { 146 | pii cur = fib.top(); 147 | fib.pop(); 148 | int v = cur.second, dis = cur.first; 149 | d[v] = dis; 150 | ve &e = edges[v]; 151 | for (int i = 0; i < e.size(); ++i) 152 | { 153 | int to = e[i].to; 154 | if (d[v] + e[i].w < d[to]) 155 | { 156 | d[to] = d[v] + e[i].w; 157 | fib.decreaseKey(nodes[to], { d[to],to }); 158 | } 159 | } 160 | } 161 | } 162 | 163 | inline int read() 164 | { 165 | static char ch; 166 | bool sgn = false; 167 | while ((ch = getchar()) < '0' || ch > '9') 168 | if (ch == '-') 169 | sgn = true; 170 | int res = ch - 48; 171 | while ((ch = getchar()) >= '0' && ch <= '9') 172 | res = res * 10 + ch - 48; 173 | return sgn ? -res : res; 174 | } 175 | 176 | int main() 177 | { 178 | v_cnt = read(), e_cnt = read(); 179 | int s = read(); 180 | while (e_cnt--) 181 | { 182 | int from = read(), to = read(), w = read(); 183 | edges[from].push_back(Edge(to, w)); 184 | } 185 | dijkstra(s); 186 | for (int i = 1; i <= v_cnt; ++i) 187 | printf("%d ", d[i] == inf ? 2147483647 : d[i]); 188 | return 0; 189 | } 190 | -------------------------------------------------------------------------------- /sequential/Vector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace ds 6 | { 7 | template 8 | class Vector 9 | { 10 | const static int InitialCap = 8; 11 | const static bool NonTrivial = !std::is_trivially_copyable::value || !std::is_trivially_destructible::value; 12 | void realloc(int newCap) 13 | { 14 | //realloc:尝试追加内存;失败则新申请内存并bitwise拷贝 15 | arr = (K*)std::realloc(arr, sizeof(K) * newCap); 16 | cap = newCap; 17 | } 18 | void expand() 19 | { 20 | if (siz == cap) 21 | realloc(cap << 1); 22 | } 23 | static void destruct(K *first, K *last) 24 | { 25 | if (NonTrivial) 26 | for (; first != last; ++first) 27 | first->~K(); 28 | } 29 | static void destruct(K *pos) { pos->~K(); } 30 | template 31 | static void construct(K *pos, Args &&...args) { new(pos) K(std::forward(args)...); } 32 | static int calc(int len) 33 | { 34 | int cap = InitialCap; 35 | for (; cap < len; cap <<= 1); 36 | return cap; 37 | } 38 | protected: 39 | int siz = 0; 40 | int cap = 0; 41 | K * arr = nullptr; 42 | static void mov(K *dest, const K *first, const K *last) //放弃原来的 43 | { 44 | memmove(dest, first, (last - first) * sizeof(K)); 45 | } 46 | static void cpy(K *dest, const K *first, const K *last) //保留原来的 47 | { 48 | if (NonTrivial) 49 | for (; first != last; ++dest, ++first) 50 | new(dest) K(*first); 51 | else 52 | memcpy(dest, first, (last - first) * sizeof(K)); 53 | } 54 | public: 55 | void push_back(K key) 56 | { 57 | expand(); 58 | construct(arr + siz++, std::move(key)); 59 | } 60 | void add_all(const Vector &rhs) 61 | { 62 | reserve(siz + rhs.siz); 63 | cpy(arr + siz, rhs.begin(), rhs.end()); 64 | siz += rhs.siz; 65 | } 66 | void resize(int nSize) 67 | { 68 | if (nSize == siz) 69 | return; 70 | if (siz < nSize) 71 | { 72 | reserve(calc(nSize)); 73 | for (K *cur = arr + siz, *last = arr + nSize; cur != last; ++cur) 74 | construct(cur, K()); 75 | } 76 | else 77 | destruct(arr + nSize, arr + siz); 78 | siz = nSize; 79 | } 80 | void pop_back() { destruct(arr + --siz); } 81 | void erase(int pos, int cnt = 1) 82 | { 83 | cnt = min(siz - pos, cnt); 84 | if (!cnt) 85 | return; 86 | destruct(arr + pos, arr + pos + cnt); 87 | mov(arr + pos, arr + pos + cnt, arr + siz); 88 | //注意到,对于类类型会产生siz和siz-1位置两个bit完全一致的版本 89 | //但是这并不会有什么问题,因为不可能再对siz位置的对象调用析构函数 90 | siz -= cnt; 91 | } 92 | void insert(int pos, K key) //insert and be there 93 | { 94 | expand(); 95 | mov(arr + pos + 1, arr + pos, arr + siz); 96 | construct(arr + pos, std::move(key)); 97 | } 98 | void reserve(int nCap) 99 | { 100 | nCap = calc(nCap); 101 | if (nCap > cap) 102 | realloc(nCap); 103 | } 104 | K *begin() { return arr; } 105 | K *end() { return arr + siz; } 106 | const K *begin() const { return arr; } 107 | const K *end() const { return arr + siz; } 108 | K &front() { return *arr; } 109 | K &back() { return *(arr + siz - 1); } 110 | const K &front() const { return *arr; } 111 | const K &back() const { return *(arr + siz - 1); } 112 | bool empty() const { return siz == 0; } 113 | int size() const { return siz; } 114 | int capacity() const { return cap; } 115 | K &operator[](int pos) { return arr[pos]; } 116 | const K &operator[](int pos) const { return arr[pos]; } 117 | Vector(int size = 0) 118 | : siz(size), cap(max(calc(siz),InitialCap)), arr((K *)malloc(cap * sizeof(K))) 119 | { 120 | for (K *cur = arr, *last = arr + siz; cur != last; ++cur) 121 | construct(cur, K()); 122 | } 123 | void swap(Vector &rhs) noexcept 124 | { 125 | std::swap(arr, rhs.arr); 126 | std::swap(siz, rhs.siz); 127 | std::swap(cap, rhs.cap); 128 | } 129 | Vector &operator=(Vector rhs) 130 | { 131 | swap(*this, rhs); 132 | return *this; 133 | } 134 | Vector(const Vector &rhs) : arr(nullptr) 135 | { 136 | reserve(rhs.siz); 137 | siz = rhs.siz; 138 | cpy(arr, rhs.begin(), rhs.end()); 139 | } 140 | Vector &operator=(Vector &&rhs) noexcept 141 | { 142 | if (this != &rhs) 143 | { 144 | Vector tmp(std::move(rhs)); 145 | swap(tmp); 146 | } 147 | return *this; 148 | } 149 | Vector(Vector &&rhs) noexcept 150 | { 151 | arr = rhs.arr; 152 | cap = rhs.cap, siz = rhs.siz; 153 | rhs.arr = nullptr; 154 | } 155 | Vector(const std::initializer_list &rhs) 156 | { 157 | reserve(rhs.size()); 158 | siz = rhs.size(); 159 | cpy(arr, rhs.begin(), rhs.end()); 160 | } 161 | ~Vector() 162 | { 163 | if (arr) 164 | { 165 | destruct(arr, arr + siz); 166 | free(arr); 167 | } 168 | } 169 | }; 170 | } -------------------------------------------------------------------------------- /associative/Treap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Util.h" 4 | #include 5 | #include 6 | #include "TreeUtil.h" 7 | namespace ds 8 | { 9 | template 10 | class Treap 11 | { 12 | private: 13 | typedef typename Traits::KeyType KeyType; 14 | typedef typename Traits::ValueType ValueType; 15 | typedef typename Traits::KeyCompare KeyCompare; 16 | KeyCompare comp; 17 | public: 18 | struct Node; 19 | typedef Node* LinkType; 20 | typedef std::pair NodePair; 21 | struct Node 22 | { 23 | LinkType p = nullptr, ch[2] = { nullptr }; 24 | ValueType value; 25 | int sz = 0; 26 | uint32_t priority = 0u; 27 | const KeyType &key() const { return Traits::KeyOf(value); } 28 | ValueType &operator*() { return value; } 29 | ValueType *operator->() { return &(operator*()); } 30 | Node() = default; 31 | Node(LinkType p, LinkType l, LinkType r, const ValueType &value) :p(p), value(value), sz(1) 32 | { 33 | ch[0] = l, ch[1] = r; 34 | priority = rawRani(); 35 | } 36 | }; 37 | private: 38 | LinkType nil_, root_; //大根堆 39 | static void updSz(LinkType x) { x->sz = x->ch[0]->sz + x->ch[1]->sz + 1; } 40 | void rotate(LinkType x) //把x向上旋转 41 | { 42 | LinkType p = x->p, g = p->p; 43 | const bool rx = x == p->ch[1], rp = p == g->ch[1]; 44 | x->p = g; //把x接到g上 45 | g->ch[rp] = x; 46 | p->ch[rx] = x->ch[!rx]; //把p的与x异侧的孙节点接到p上 47 | x->ch[!rx]->p = p; 48 | p->p = x; //把p接到x上 49 | x->ch[!rx] = p; 50 | if (root_ == p) 51 | root_ = x; 52 | updSz(p), updSz(x); 53 | } 54 | void transplant(LinkType dest, LinkType sour)//并不处理dest的子节点 55 | { 56 | LinkType dp = dest->p; 57 | sour->p = dp; 58 | if (dp == nil_) 59 | root_ = sour; 60 | else 61 | dp->ch[dest == dp->ch[1]] = sour; 62 | } 63 | public: 64 | LinkType nextNode(Node *x)const { return TreeUtil::nextNode(x, nil_); } 65 | LinkType prevNode(Node *x)const { return TreeUtil::prevNode(x, nil_, root_); } 66 | LinkType kth(const int k)const { return TreeUtil::kth(root_, nil_, k); } 67 | int lower(const KeyType &key, const bool afterEqual) const { return TreeUtil::lower(key, root_, nil_, afterEqual, comp); } 68 | NodePair findNode(const KeyType &key, LinkType x = nullptr) //从x开始搜 69 | { 70 | if (!x) x = root_; 71 | LinkType p = nil_; 72 | while (x != nil_) 73 | { 74 | if (comp(x->key(), key)) 75 | p = x, x = x->ch[1]; 76 | else if (!comp(key, x->key())) 77 | return { x,p }; 78 | else 79 | p = x, x = x->ch[0]; 80 | } 81 | return { nullptr,p }; 82 | } 83 | LinkType insert(LinkType x, const ValueType &value) 84 | { 85 | LinkType z = new Node(x, nil_, nil_, value); 86 | if (x == nil_) root_ = z; 87 | else x->ch[comp(x->key(), Traits::KeyOf(value))] = z; 88 | LinkType tmpx = x; 89 | while (tmpx != nil_) 90 | ++tmpx->sz, tmpx = tmpx->p; 91 | while (z != root_ && z->priority > z->p->priority)//一旦z的priority没有z->p高,可以立即停止更新 92 | rotate(z); 93 | return z; 94 | } 95 | LinkType insert(const ValueType &value) 96 | { 97 | NodePair np = findNode(Traits::KeyOf(value)); 98 | if (np.first) 99 | return np.first; 100 | return insert(np.second, value); 101 | } 102 | void erase(LinkType z) 103 | { 104 | //把z转到最底层,从而直接删除 105 | z->priority = 0u; 106 | while (z->ch[0] != nil_&&z->ch[1] != nil_) 107 | { 108 | const int argmax = z->ch[0]->priority < z->ch[1]->priority; 109 | rotate(z->ch[argmax]); 110 | } 111 | LinkType tmpz = z; 112 | while (tmpz != nil_) 113 | --tmpz->sz, tmpz = tmpz->p; 114 | const int argnil = z->ch[1] == nil_; 115 | transplant(z, z->ch[!argnil]); 116 | delete z; 117 | } 118 | void check(Node *x) 119 | { 120 | if (x == nil_) 121 | return; 122 | //if (x->ch[0]->priority > x->priority || x->ch[1]->priority>x->priority) 123 | if (x->ch[0]->sz+x->ch[1]->sz+1!=x->sz) 124 | std::cout << "fuck it\n"; 125 | check(x->ch[0]); 126 | check(x->ch[1]); 127 | } 128 | void bfs() 129 | { 130 | std::queue q; 131 | q.push(root_); 132 | while (!q.empty()) 133 | { 134 | std::queue layer; 135 | while (!q.empty()) 136 | { 137 | LinkType x = q.front(); 138 | q.pop(); 139 | printf("(%d,%u) ", (*x)->first, x->priority); 140 | for (int i = 0; i<2; ++i) 141 | if (x->ch[i] != nil_) 142 | layer.push(x->ch[i]); 143 | } 144 | std::cout << std::endl; 145 | q = layer; 146 | } 147 | std::cout << std::endl; 148 | } 149 | LinkType minChild() const { return TreeUtil::extremeChild(root_, nil_, 0); } 150 | LinkType maxChild() const { return TreeUtil::extremeChild(root_, nil_, 1); } 151 | int size() const { return root_->sz; } 152 | LinkType nil() const { return nil_; } 153 | Treap(KeyCompare comp = KeyCompare()) :comp(comp), nil_(new Node) 154 | { 155 | root_ = nil_; 156 | root_->p = root_->ch[0] = root_->ch[1] = nil_; 157 | } 158 | Treap(const Treap &) = delete; 159 | Treap& operator=(const Treap &) = delete; 160 | }; 161 | } -------------------------------------------------------------------------------- /integer/vEBTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace ds 6 | { 7 | namespace vEB 8 | { 9 | constexpr int lodiv2(int i) { return i >> 1; } 10 | constexpr int hidiv2(int i) { return (i >> 1) + (i & 1); } 11 | template 12 | struct Node 13 | { 14 | int min = -1, max = -1; 15 | //原来之所以不得不用指针,只是因为不同大小的Node都是一个类型 16 | //现在它们是不同类型的,不再需要指针,也不需要递归建树 17 | Node summary; 18 | Node clusters[1 << hidiv2(N)]; 19 | constexpr static int highPart(int x) { return x >> lodiv2(N); } 20 | constexpr static int lowPart(int x) { return x & ((1 << lodiv2(N)) - 1); } 21 | constexpr static int numOf(int hi, int lo) { return (hi << lodiv2(N)) + lo; } 22 | }; 23 | template <> 24 | struct Node<1> //由于C++不允许类内特例化,故而放在外面的命名空间里 25 | { 26 | int min = -1, max = -1; 27 | }; 28 | } 29 | template //最终vEB树的容量是2^Size 30 | class vEBTree 31 | { 32 | private: 33 | vEB::Node root; 34 | std::bitset<1 << Size> table; //O(1)exist查询 35 | template 36 | static void putOnEmpty(vEB::Node &z, int x) { z.min = z.max = x; } 37 | template 38 | static void insert(vEB::Node &z,int x) 39 | { 40 | if (z.min == -1) //min为-1意味着max也为-1,空节点直接插 41 | putOnEmpty(z, x); 42 | else 43 | { 44 | if (x < z.min) 45 | std::swap(x, z.min); 46 | //此时N > 1 47 | const int hi = z.highPart(x), lo = z.lowPart(x); 48 | if (z.clusters[hi].min == -1) 49 | { 50 | insert(z.summary, z.highPart(x));//本簇中没有元素,需要修改summary 51 | putOnEmpty(z.clusters[hi], lo); 52 | } 53 | else //本簇中有元素 54 | insert(z.clusters[hi], lo); 55 | if (x > z.max)//insert完了之后才修改,如果要改循环,需要独立出去 56 | z.max = x; 57 | } 58 | } 59 | static void insert(vEB::Node<1> &z,int x) 60 | { 61 | if (z.min == -1) //min为-1意味着max也为-1,空节点直接插 62 | putOnEmpty(z, x); 63 | else 64 | { 65 | if (x < z.min) 66 | std::swap(x, z.min); 67 | if (z.max < x) 68 | z.max = x; 69 | } 70 | } 71 | template 72 | static void erase(vEB::Node &z, int x) 73 | { 74 | if (z.max == z.min) //有且只有一个元素 75 | z.max = z.min = -1; 76 | else 77 | { 78 | if (x == z.min) //在簇中找一个元素来当新min 79 | { 80 | const int firstCluster = z.summary.min; //第一个非空的簇 81 | x = z.numOf(firstCluster, z.clusters[firstCluster].min); //那个簇中的第一个元素 82 | z.min = x; 83 | } 84 | erase(z.clusters[z.highPart(x)], z.lowPart(x)); 85 | //以上完成了对簇的修改,以下解决簇为空之后的summary和维护max 86 | if (z.clusters[z.highPart(x)].min == -1) //刚删完的簇变空了 87 | { 88 | erase(z.summary, z.highPart(x)); 89 | if (x == z.max) //删掉的是max,需更新之;对于min的处理在上面; 90 | { 91 | const int maxSummary = z.summary.max; //由于用到了summary,对max的维护放在对summary的维护之后 92 | if (maxSummary == -1) 93 | z.max = z.min; 94 | else z.max = z.numOf(maxSummary, z.clusters[maxSummary].max); 95 | } 96 | } 97 | else if (x == z.max) 98 | z.max = z.numOf(z.highPart(x), z.clusters[z.highPart(x)].max); 99 | } 100 | } 101 | static void erase(vEB::Node<1> &z, int x) 102 | { 103 | if (z.max == z.min) //有且只有一个元素 104 | z.max = z.min = -1; 105 | else 106 | z.max = z.min = !x; 107 | } 108 | 109 | template 110 | static int findNext(const vEB::Node &z, int x) 111 | { 112 | if (x < z.min) //无需判断z.min是不是-1 113 | return z.min; 114 | const int inClusterMax = z.clusters[z.highPart(x)].max; 115 | if (inClusterMax != -1 && z.lowPart(x) &z, int x) { return (x == 0 && z.max == 1) ? 1 : -1; } 123 | 124 | template 125 | static int findPrev(const vEB::Node &z, int x) 126 | { 127 | if (x > z.max) //无需判断z.max是不是-1 128 | return z.max; 129 | const int clusterMin = z.clusters[z.highPart(x)].min; 130 | if (clusterMin != -1 && clusterMin < z.lowPart(x)) 131 | return z.numOf(z.highPart(x), findPrev(z.clusters[z.highPart(x)], z.lowPart(x))); 132 | const int prevCluster = findPrev(z.summary, z.highPart(x)); 133 | if (prevCluster == -1) //z.min并不存在于cluster中,要特判 134 | return x > z.min ? z.min : -1; //无需判断z.min是不是-1 135 | return z.numOf(prevCluster, z.clusters[prevCluster].max); 136 | } 137 | static int findPrev(const vEB::Node<1> &z, int x) { return (x == 1 && z.min == 0) ? 0 : -1; } 138 | 139 | public: 140 | int findMin() const { return root.min; } 141 | int findMax() const { return root.max; } 142 | bool exist(int x) const { return table[x]; } 143 | void insert(int x) 144 | { 145 | if (!table[x]) 146 | table[x] = true, insert(root, x); 147 | } 148 | void erase(int x) 149 | { 150 | if (table[x]) 151 | table[x] = false, erase(root, x); 152 | } 153 | int findNext(int x) { return findNext(root, x); } 154 | int findPrev(int x) { return findPrev(root, x); } 155 | }; 156 | } 157 | -------------------------------------------------------------------------------- /associative/Splay.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace ds 6 | { 7 | template 8 | class Splay 9 | { 10 | private: 11 | typedef typename Traits::KeyType KeyType; 12 | typedef typename Traits::ValueType ValueType; 13 | typedef typename Traits::KeyCompare KeyCompare; 14 | KeyCompare comp; 15 | public: 16 | struct Node; 17 | typedef Node* LinkType; 18 | typedef std::pair NodePair; 19 | struct Node 20 | { 21 | LinkType p = nullptr, ch[2] = { nullptr }; 22 | ValueType value; 23 | int sz = 0; 24 | const KeyType &key() const { return Traits::KeyOf(value); } 25 | ValueType &operator*() { return value; } 26 | ValueType *operator->() { return &(operator*()); } 27 | bool isRight()const { return this == p->ch[1]; } 28 | LinkType clone(LinkType p, LinkType l, LinkType r) const 29 | { 30 | LinkType ret = new Node(p, l, r, ValueType(value)); 31 | ret->sz = sz; 32 | return ret; 33 | } 34 | Node() = default; 35 | Node(LinkType p, LinkType l, LinkType r, const ValueType &value) :p(p), value(value), sz(1) { ch[0] = l, ch[1] = r; } 36 | }; 37 | private: 38 | LinkType nil_, root_; 39 | static void updSz(LinkType x) { x->sz = x->ch[0]->sz + x->ch[1]->sz + 1; } 40 | void rotate(LinkType x) //把x向上旋转 41 | { 42 | LinkType p = x->p, g = p->p; 43 | const bool rx = x == p->ch[1], rp = p == g->ch[1]; 44 | x->p = g; //把x接到g上 45 | g->ch[rp] = x; 46 | p->ch[rx] = x->ch[!rx]; //把p的与x异侧的孙节点接到p上 47 | x->ch[!rx]->p = p; 48 | p->p = x; //把p接到x上 49 | x->ch[!rx] = p; 50 | if (root_ == p) 51 | root_ = x; 52 | updSz(p), updSz(x); 53 | } 54 | void splay(const LinkType dest, LinkType sour) 55 | { 56 | while (sour->p != dest) 57 | { 58 | LinkType p = sour->p; 59 | if (p->p != dest) //避免错过 60 | (p->isRight() == sour->isRight()) ? rotate(p) : rotate(sour); 61 | rotate(sour); 62 | } 63 | if (dest == nil_) 64 | sour = root_; 65 | } 66 | void transplant(LinkType dest, LinkType sour) 67 | { 68 | LinkType dp = dest->p; 69 | sour->p = dp; 70 | if (dp == nil_) 71 | root_ = sour; 72 | else 73 | dp->ch[dest == dp->ch[1]] = sour; 74 | } 75 | public: 76 | LinkType nextNode(Node *x)const { return TreeUtil::nextNode(x, nil_); } 77 | LinkType prevNode(Node *x)const { return TreeUtil::prevNode(x, nil_, root_); } 78 | LinkType kth(const int k) //Splay的顺序统计操作必须进行splay,否则会卡链 79 | { 80 | LinkType ret = TreeUtil::kth(root_, nil_, k); 81 | splay(nil_, ret); 82 | return ret; 83 | } 84 | int lower(const KeyType &key, const bool afterEqual) 85 | { 86 | findNode(key); 87 | return TreeUtil::lower(key, root_, nil_, afterEqual, comp); 88 | } 89 | NodePair findNode(const KeyType &key,const bool doSplay = true) //从x开始搜 90 | { 91 | LinkType x = root_, p = nil_; 92 | while (x != nil_) 93 | { 94 | if (comp(x->key(), key)) 95 | p = x, x = x->ch[1]; 96 | else if (!comp(key, x->key())) 97 | { 98 | if (doSplay) 99 | splay(nil_, x); 100 | return { x,p }; 101 | } 102 | else 103 | p = x, x = x->ch[0]; 104 | } 105 | if (doSplay) 106 | splay(nil_, p); 107 | return { nullptr,p }; 108 | } 109 | LinkType insert(const ValueType &value) 110 | { 111 | const KeyType &key = Traits::KeyOf(value); 112 | NodePair x = findNode(key, false); 113 | if (x.first) 114 | { 115 | splay(nil_, x.first); 116 | return x.first; 117 | } 118 | LinkType px = x.second; 119 | LinkType z = new Node(px, nil_, nil_, value); 120 | if (px == nil_) root_ = z; 121 | else px->ch[comp(px->key(), key)] = z; 122 | LinkType tmpx = px; 123 | while (tmpx != nil_) 124 | ++tmpx->sz, tmpx = tmpx->p; 125 | splay(nil_, z); 126 | return z; 127 | } 128 | void erase(LinkType z) //Map里使用erase是配合find的,所以z一定是根 129 | { 130 | LinkType tmpz = z; 131 | while (tmpz != nil_) 132 | --tmpz->sz, tmpz = tmpz->p; 133 | LinkType y = z, x; 134 | if (z->ch[0] == nil_) 135 | x = z->ch[1], transplant(z, x); 136 | else if (z->ch[1] == nil_) 137 | x = z->ch[0], transplant(z, x); 138 | else 139 | { 140 | y = TreeUtil::extremeChild(z->ch[1], nil_, 0); 141 | x = y->ch[1]; 142 | if (y->p == z) 143 | x->p = y; 144 | else 145 | { 146 | LinkType tmpy = y; 147 | while (tmpy != z) 148 | { 149 | --tmpy->sz; 150 | tmpy = tmpy->p; 151 | } 152 | transplant(y, x); 153 | y->ch[1] = z->ch[1]; //把y剥离出来,安到z的位置 154 | y->ch[1]->p = y; 155 | } 156 | transplant(z, y); 157 | y->ch[0] = z->ch[0], y->ch[0]->p = y; 158 | updSz(y); 159 | } 160 | } 161 | LinkType minChild() const { return TreeUtil::extremeChild(root_, nil_, 0); } 162 | LinkType maxChild() const { return TreeUtil::extremeChild(root_, nil_, 1); } 163 | int size() const { return root_->sz; } 164 | LinkType nil() const { return nil_; } 165 | void clear() { TreeUtil::clear(root_, nil_); } 166 | Splay(KeyCompare comp = KeyCompare()) :comp(comp), nil_(new Node) 167 | { 168 | root_ = nil_; 169 | root_->p = root_->ch[0] = root_->ch[1] = nil_; 170 | } 171 | Splay(const Splay&rhs) = delete;//为了保证Splay的简洁(滑稽),不做拷贝控制和析构 172 | Splay& operator=(const Splay&rhs) = delete; 173 | }; 174 | } 175 | -------------------------------------------------------------------------------- /heap/PairingHeap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | namespace ds 3 | { 4 | //算法借鉴了gnu pbds,实现了O(1)空间pop (递归merge也是O(n)的,而且是栈空间O(n)) 5 | //另有一个很简单的实现,O(n)空间pop,而且慢一些,在后面被注释掉了(其实真正做题不会用vector,所以也不会跑的很慢) 6 | //二者的思想是完全相同的,虽然看起来很不一样 7 | 8 | template 9 | class PairingHeap //最小堆 10 | { 11 | public: 12 | class Node 13 | { 14 | K key; 15 | Node *porp = nullptr; //prev or parent 16 | Node *ch = nullptr; 17 | Node *next = nullptr; 18 | Node(const K &key) :key(key) {} 19 | friend PairingHeap; 20 | public: 21 | const K &getKey()const { return key; } 22 | }; 23 | private: 24 | Node *root = nullptr; 25 | static Node* merge(Node *dest, Node *sour) 26 | { 27 | if (!dest) return sour; 28 | if (!sour) return dest; 29 | if (sour->key < dest->key) 30 | std::swap(dest, sour); 31 | makeChildOf(sour, dest); 32 | return dest; 33 | } 34 | static void makeChildOf(Node *ch, Node *p) 35 | { 36 | ch->next = p->ch; 37 | if (p->ch) 38 | p->ch->porp = ch; //这里的porp是prev 39 | ch->porp = p; 40 | p->ch = ch; 41 | } 42 | static Node *joinChild(Node *p) 43 | { 44 | /* 45 | 与后面的代码的对应: 46 | fwdJoin等价于 47 | for (int i = 0; i < chs.size(); i += 2) 48 | aux.push_back(merge(chs[i], chs[i + 1])); //一对一对合并 49 | backJoin等价于 50 | for (int i = 0; i < aux.size(); ++i) 51 | root = merge(root, aux[i]); //把这些对合并起来 52 | */ 53 | Node *ret = p->ch; 54 | if (!ret) 55 | return nullptr; 56 | while (ret->next) 57 | ret = fwdJoin(ret, ret->next); //每次merge一对,Paring的名字来源 58 | while (ret->porp != p) 59 | ret = backJoin(ret->porp, ret); 60 | return ret; 61 | } 62 | static Node *fwdJoin(Node *cur, Node *nxt) 63 | { 64 | if (nxt->key < cur->key) //nxt作为根,cur作为孩子 65 | { 66 | nxt->porp = cur->porp; //链表删除 67 | makeChildOf(cur, nxt); //没有修改cur->next是因为makeChildOf里面修改了 68 | return nxt->next ? nxt->next : nxt; 69 | } 70 | if (nxt->next) //cur作为根,nxt作为孩子;判一下nxt->next才能执行链表删除 71 | { 72 | nxt->next->porp = cur; 73 | cur->next = nxt->next; //链表删除 74 | makeChildOf(nxt, cur); 75 | return cur->next; 76 | } 77 | //特判nxt->next为空 78 | cur->next = nullptr; 79 | makeChildOf(nxt, cur); 80 | return cur; 81 | } 82 | static Node *backJoin(Node *pre, Node *cur) 83 | { 84 | if (cur->key < pre->key) //cur作为根 85 | { 86 | cur->porp = pre->porp; 87 | makeChildOf(pre, cur); 88 | return cur; 89 | } 90 | pre->next = nullptr; //pre作为根,直接把pre之后的 [所有节点] 加入它的孩子 91 | makeChildOf(cur, pre); 92 | return pre; 93 | } 94 | public: 95 | PairingHeap() = default; 96 | Node *push(const K &key) 97 | { 98 | Node *ret = new Node(key); 99 | root = merge(root, ret); 100 | return ret; 101 | } 102 | void merge(PairingHeap &rhs) { root = merge(root, rhs.root); } 103 | const K &top() const { return root->key; } 104 | bool empty() const { return !root; } 105 | void pop() { root = joinChild(root); } 106 | void decreaseKey(Node *x,const K &key) 107 | { 108 | x->key = key; 109 | if (x == root) 110 | return; 111 | //链表删除 112 | if (x->next) 113 | x->next->porp = x->porp; 114 | if (x->porp->next == x) //porp 是 prev 115 | x->porp->next = x->next; 116 | else //porp 是 parent 117 | x->porp->ch = x->next; 118 | x->porp = nullptr; 119 | root = merge(root, x); 120 | } 121 | }; 122 | /*template 123 | class PairingHeap 124 | { 125 | public: 126 | struct Node //最小堆 127 | { 128 | K key; 129 | Node *p = nullptr; 130 | Node *ch = nullptr; //左孩子-右兄弟式树 131 | Node *next = nullptr; 132 | Node(const K &key) :key(key) {} 133 | }; 134 | private: 135 | Node *root = nullptr; 136 | PairingHeap(const K &key) : root(new Node(key)) {} 137 | static Node* merge(Node *dest,Node *sour) 138 | { 139 | if (!dest) return sour; 140 | if (!sour) return dest; 141 | if (dest->key > sour->key) 142 | std::swap(dest, sour); 143 | sour->p = dest; 144 | Node *tmp = dest->ch; 145 | dest->ch = sour; 146 | sour->next = tmp; //插入链表前端 147 | return dest; 148 | } 149 | 150 | //@Deprecated 151 | static Node *mergePair(Node *ch) //一对一对的merge,名字来源 152 | { 153 | if (!ch || !ch->next) 154 | return ch; 155 | return merge(merge(ch, ch->next), mergePair(ch->next->next)); 156 | //想法很美好,均摊时间复杂度也有保证 157 | //但是很可惜,一大堆push之后的第一次pop会导致栈溢出 158 | } 159 | public: 160 | PairingHeap() = default; 161 | void merge(PairingHeap &rhs) { merge(root, rhs.root); } 162 | Node *push(const K &key) 163 | { 164 | Node *ret = new Node(key); 165 | root = merge(root, ret); 166 | return ret; 167 | } 168 | const K &top() const { return root->key; } 169 | bool empty() const { return !root; } 170 | void pop() 171 | { 172 | //root = mergePair(root->ch); //栈溢出 173 | static std::vector chs; //一个技巧,vector的clear/pop_back不会释放内存,所以这样可以避免反复申请/释放内存 174 | static std::vector aux; 175 | chs.clear(), aux.clear(); 176 | for (Node *ch = root->ch; ch; ch = ch->next) 177 | chs.push_back(ch); 178 | if (chs.size() & 1) 179 | chs.push_back(nullptr); 180 | for (int i = 0; i < chs.size(); i += 2) 181 | aux.push_back(merge(chs[i], chs[i + 1])); 182 | root = nullptr; 183 | for (int i = 0; i < aux.size(); ++i) 184 | root = merge(root, aux[i]); 185 | } 186 | };*/ 187 | 188 | } -------------------------------------------------------------------------------- /sequential/String.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Vector.h" 3 | #include "Util.h" 4 | #include 5 | namespace ds 6 | { 7 | class StringView 8 | { 9 | private: 10 | const char *first; 11 | const char *last; 12 | static int *buildKMP(const StringView &rhs) 13 | { 14 | int *nxt = new int[rhs.size()]; 15 | memset(nxt, 0, rhs.size() * sizeof(int)); 16 | for (int i = 1, k = 0; i < rhs.size(); ++i) 17 | { 18 | while (k && rhs[k] != rhs[i]) 19 | k = nxt[k - 1]; 20 | nxt[i] = k += rhs[k] == rhs[i]; 21 | } 22 | return nxt; 23 | } 24 | public: 25 | const static int npos = ~(1 << 31); 26 | typedef const char * iterator; 27 | char operator[](int k)const { return first[k]; } 28 | iterator begin() const { return first; } 29 | iterator end() const { return last; } 30 | StringView(const char *first, const char *last = nullptr) :first(first) 31 | { 32 | this->last = last ? last : (first + strlen(first)); 33 | } 34 | int size()const { return last - first; } 35 | void removeSuffix(int cnt = 1) { last -= cnt; } 36 | void removePrefix(int cnt = 1) { first += cnt; } 37 | StringView substr(int pos, int cnt = npos) const 38 | { 39 | cnt = min(cnt, size() - pos); 40 | return StringView(first + pos, first + pos + cnt); 41 | } 42 | struct KMP {}; 43 | struct Brute {}; 44 | struct KarpRabin {}; 45 | struct BoyerMoore {}; 46 | int find(const StringView &rhs, KMP) const 47 | { 48 | int *nxt = buildKMP(rhs); 49 | int i, k; 50 | for (i=0,k=0;i findAll(const StringView &rhs, KMP) const 62 | { 63 | int *nxt = buildKMP(rhs); 64 | Vector ret; 65 | int i, k; 66 | for (i = 0, k = 0; i findAll(const StringView &rhs,KarpRabin) const 97 | { 98 | const int p = 127; 99 | typedef unsigned long long ull; 100 | Vector ret; 101 | ull rhsHash = 0, selfHash = 0, hi = 1; 102 | for (int i = 0; i < rhs.size(); ++i) 103 | rhsHash = rhsHash * p + rhs[i], (i ? hi *= p : 0); 104 | for (int i = 0; i < rhs.size(); ++i) 105 | selfHash = selfHash * p + operator[](i); 106 | if (selfHash == rhsHash) 107 | ret.push_back(0); 108 | for (int i = rhs.size(); i < size(); ++i) 109 | { 110 | selfHash = (selfHash - operator[](i - rhs.size()) * hi) * p + operator[](i); 111 | if (selfHash == rhsHash) 112 | ret.push_back(i + 1 - rhs.size()); 113 | } 114 | return ret; 115 | } 116 | }; 117 | class String : public Vector 118 | { 119 | friend std::ostream& operator<<(std::ostream& os, const String &rhs) //不支持中文 120 | { 121 | for (auto ch : rhs) 122 | os << ch; 123 | return os; 124 | } 125 | friend std::istream& operator>>(std::istream& is, String &rhs) 126 | { 127 | char ch; 128 | while (is.get(ch) && isspace(ch)); 129 | rhs.push_back(ch); 130 | while (is.get(ch) && !isspace(ch)) 131 | rhs.push_back(ch); 132 | return is; 133 | } 134 | public: 135 | const static int npos = ~(1 << 31); 136 | String(const char *ptr) 137 | { 138 | const int len = strlen(ptr); 139 | reserve(len); 140 | cpy(arr, ptr, ptr + len); 141 | siz = len; 142 | } 143 | String() = default; 144 | String& operator+=(char c) { return push_back(c), *this; } 145 | String& operator+=(const String &rhs) { return add_all(rhs), *this; } 146 | String& operator+=(const char *ptr) 147 | { 148 | const int len = strlen(ptr); 149 | reserve(len + siz); 150 | cpy(arr + siz, ptr, ptr + len); 151 | siz += len; 152 | return *this; 153 | } 154 | template 155 | String operator+(K &&k) const 156 | { 157 | String tmp(*this); 158 | tmp += std::forward(k); 159 | return tmp; 160 | } 161 | operator StringView() const { return StringView(begin(), end()); } 162 | template 163 | int find(const StringView &rhs, Mode) { return StringView(*this).find(rhs, Mode()); } 164 | template 165 | Vector findAll(const StringView &rhs, Mode) { return StringView(*this).findAll(rhs, Mode()); } 166 | }; 167 | template 168 | String operator+(K &&k, const String &rhs) 169 | { 170 | return rhs + std::forward(k); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /sequential/ForwardList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ds 5 | { 6 | //没有哨兵节点的单向链表 7 | //与stl一样,没有保存size,额外提供了一个size()函数,O(n)的,正常情况下都不要用 8 | template 9 | class ForwardList 10 | { 11 | public: 12 | class iterator; 13 | friend iterator; 14 | private: 15 | struct Node 16 | { 17 | K key; 18 | Node *next; 19 | explicit Node(const K &key, Node *next = nullptr) :key(key), next(next) {} 20 | }; 21 | Node *head = nullptr; 22 | static void extract_after(iterator pre1,iterator pre2) 23 | { 24 | Node *ext = pre2.nextNode(); 25 | pre2.nextNode() = ext->next; 26 | ext->next = pre1.nextNode(); 27 | pre1.nextNode() = ext; 28 | } 29 | public: 30 | class iterator 31 | { 32 | public: 33 | typedef std::forward_iterator_tag iterator_category; 34 | typedef K value_type; 35 | typedef int difference_type; 36 | typedef K *pointer; 37 | typedef K &reference; 38 | typedef const K &const_reference; 39 | typedef const K *const_pointer; 40 | friend ForwardList; 41 | private: 42 | Node *self; 43 | ForwardList *container; 44 | Node *&nextNode() //注意返回值是引用 45 | { 46 | if (!self) 47 | return container->head; 48 | return self->next; 49 | } 50 | public: 51 | K & operator*() { return self->key; } 52 | K * operator->() { return &(self->key); } 53 | iterator& operator++() 54 | { 55 | self = self ? self->next : container->head; //这样可以自然构建循环链表,以时间换空间 56 | return *this; 57 | } 58 | iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; } 59 | bool operator==(iterator rhs) const { return self == rhs.self; } 60 | bool operator!=(iterator rhs) const { return self != rhs.self; } 61 | iterator(Node *self,ForwardList *container) :self(self),container(container) {} 62 | }; 63 | void push_front(const K &key) 64 | { 65 | head = new Node(key, head); 66 | } 67 | void pop_front() 68 | { 69 | Node *tmp = head->next; 70 | delete head; 71 | head = tmp; 72 | } 73 | iterator insert_after(Node *where,const K &key) 74 | { 75 | if (!where) //before begin 76 | { 77 | push_front(key); 78 | return { head,this }; 79 | } 80 | Node *ins = new Node(key, where->next); 81 | where->next = ins; 82 | return { ins ,this }; 83 | } 84 | iterator erase_after(Node *where) //返回where->next->next 85 | { 86 | if (!where) //before begin 87 | { 88 | pop_front(); 89 | return { head ,this }; 90 | } 91 | Node *era = where->next, ret = era->next; //显然不能erase_after最后一个元素 92 | delete era; 93 | where->next = ret; 94 | return { ret ,this }; 95 | } 96 | template 97 | void remove_if(Pred pred) 98 | { 99 | if (pred(head)) 100 | { 101 | pop_front(); 102 | return; 103 | } 104 | Node *cur = head; 105 | while (cur->next) 106 | if (pred(cur->next->key)) 107 | { 108 | Node *tmp = cur->next; 109 | cur->next = cur->next->next; 110 | delete tmp; 111 | } 112 | else 113 | cur = cur->next; 114 | } 115 | int size() const 116 | { 117 | Node *cur = head; 118 | int ret = 0; 119 | while (cur) 120 | ++ret, cur = cur->next; 121 | return ret; 122 | } 123 | bool empty() const { return !head; } 124 | iterator begin() { return { head ,this }; } 125 | iterator end() { return { nullptr,this }; } 126 | iterator before_begin() { return end(); } 127 | void reverse() 128 | { 129 | if (!head||!head->next) 130 | return; 131 | Node *cur = head, *pre = nullptr; 132 | while (cur) 133 | { 134 | Node *tmp = cur->next; 135 | if (!tmp) 136 | head = cur; //末尾节点变成头 137 | cur->next = pre; 138 | pre = cur; 139 | cur = tmp; 140 | } 141 | } 142 | void merge(ForwardList &rhs) //归并,清空rhs的内容 143 | { 144 | iterator it1 = before_begin(), it2 = rhs.before_begin(); 145 | auto cmp = [](iterator it1, iterator it2) {return it1.nextNode()->key < it2.nextNode()->key; }; 146 | while (it1.nextNode() && it2.nextNode()) 147 | { 148 | if (cmp(it2, it1)) 149 | extract_after(it1, it2); 150 | else 151 | ++it1; 152 | } 153 | if (!it1.nextNode()) 154 | { 155 | it1.nextNode() = it2.nextNode(); 156 | it2.nextNode() = nullptr; 157 | } 158 | } 159 | void swap(ForwardList &rhs) noexcept 160 | { 161 | std::swap(head, rhs.head); 162 | } 163 | void sort() 164 | { 165 | if (head && head->next) 166 | { 167 | ForwardList carry; 168 | ForwardList counter[64]; 169 | int fill = 0; 170 | while (head) 171 | { 172 | extract_after(carry.before_begin(), before_begin()); 173 | int i = 0; 174 | while (i < fill && !counter[i].empty()) 175 | { 176 | counter[i].merge(carry); 177 | carry.swap(counter[i++]); 178 | } 179 | carry.swap(counter[i]); 180 | if (i == fill) 181 | ++fill; 182 | } 183 | for (int i = 1; i < fill; ++i) 184 | counter[i].merge(counter[i - 1]); 185 | swap(counter[fill - 1]); 186 | } 187 | } 188 | ForwardList() = default; 189 | ForwardList(const ForwardList &rhs) 190 | { 191 | if (!rhs.head) 192 | return; 193 | Node *pre = head = new Node(rhs.head->key),*cur = rhs.head->next; 194 | while (cur) 195 | { 196 | pre->next = new Node(cur->key); 197 | cur = cur->next; 198 | pre = pre->next; 199 | } 200 | } 201 | ForwardList &operator=(const ForwardList &rhs) 202 | { 203 | if (this!=&rhs) 204 | { 205 | ForwardList tmp(rhs); 206 | swap(tmp); 207 | } 208 | return *this; 209 | } 210 | ForwardList(ForwardList &&rhs) noexcept 211 | { 212 | head = rhs.head; 213 | rhs.head = nullptr; 214 | } 215 | ForwardList &operator=(ForwardList &&rhs) noexcept 216 | { 217 | if (this != &rhs) 218 | { 219 | ForwardList tmp(std::move(rhs)); 220 | swap(tmp); 221 | } 222 | return *this; 223 | } 224 | ~ForwardList() 225 | { 226 | Node *cur = head; 227 | while (cur) 228 | { 229 | Node *tmp = cur->next; 230 | delete cur; 231 | cur = tmp; 232 | } 233 | } 234 | }; 235 | } 236 | -------------------------------------------------------------------------------- /toy/template/SetT.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ds 5 | { 6 | namespace stmp //stateful template metaprogramming 7 | { 8 | //大概原理是这样的:利用N个bool来维护N个状态(为什么不是lgN个bool?因为每个bool的状态只能变化一次) 9 | //每次计数器+1,都是一个constexpr函数被定义的过程 10 | //被定义的constexpr函数具有noexcept性质,不会被SFINAE( char[noexcept(adl_flag(flag())) ? +1 : -1] )判定失败 11 | //从而可以提供更好的匹配 12 | template 13 | struct flag 14 | { 15 | friend constexpr int adl_flag(flag); 16 | }; 17 | template 18 | struct writer 19 | { 20 | friend constexpr int adl_flag(flag) 21 | { 22 | return N; 23 | } 24 | static constexpr int value = N; 25 | }; 26 | template ())) ? +1 : -1]> 27 | int constexpr reader(int, flag) 28 | { 29 | return N; 30 | } 31 | template 32 | int constexpr reader(float, flag, int R = reader(0, flag())) 33 | { 34 | return R; 35 | } 36 | int constexpr reader(float, flag<0>) 37 | { 38 | return 0; 39 | } 40 | template ())> //只支持64个状态 41 | int constexpr next(int R = writer::value) 42 | { 43 | return R; 44 | } 45 | } 46 | constexpr unsigned staticRand(unsigned x) 47 | { 48 | x ^= x << 13; 49 | x ^= x >> 17; 50 | x ^= x << 5; 51 | return x; 52 | } 53 | template 54 | struct StaticRand 55 | { 56 | const static unsigned value = staticRand(StaticRand::value); 57 | }; 58 | template <> 59 | struct StaticRand<1> 60 | { 61 | const static unsigned value = 19260817u; 62 | }; 63 | 64 | template 65 | struct NullT 66 | { 67 | using Left = NullT; 68 | using Right = NullT; 69 | using ValueType = T; 70 | }; 71 | 72 | template 73 | struct IsNull 74 | { 75 | const static bool value = std::is_base_of, T>::value; 76 | }; 77 | template 78 | struct NodeT 79 | { 80 | const static unsigned pri = Pri; 81 | const static T value = Val; 82 | using Left = L; 83 | using Right = R; 84 | using ValueType = T; 85 | }; 86 | 87 | template ::value> 88 | struct OutputTree 89 | { 90 | using T = typename Tree::ValueType; 91 | template 92 | struct Outputer; 93 | OutputTree left{}; 94 | Outputer impl{}; 95 | OutputTree right{}; 96 | }; 97 | template 98 | struct OutputTree 99 | { }; 100 | 101 | template ::value> 102 | struct Split 103 | { 104 | using T = typename Node::ValueType; 105 | //如果Node的value<=Pivot,那么Node的左子树完全归入左半边,右子树继续划分出来的左子树作为Left的左子树 106 | //如果Node的value>Pivot,那么Node的右子树完全归入右半边,左子树继续划分出来的右子树作为Right的左子树 107 | using Left = typename std::conditional::Left>, 109 | typename Split::Left>::type; 110 | using Right = typename std::conditional::Right, 112 | NodeT::Right, typename Node::Right> >::type; 113 | }; 114 | template 115 | struct Split 116 | { 117 | using Left = NullT; 118 | using Right = NullT; 119 | }; 120 | template ::value || IsNull::value> 121 | struct Merge 122 | { 123 | using T = typename Left::ValueType; 124 | //Left中的元素全部小于Right中的元素 125 | //如果Left的根的优先级更高,那么把Left和Left的左孩子保持不变,Left的右孩子与Right的归并结果作为Left的右孩子 126 | //如果Right的根的优先级更高,那么把Right和Right的右孩子保持不变,Left与Right的左孩子的归并结果作为Right的左孩子 127 | using Root = typename std::conditional < (Left::pri > Right::pri), 128 | NodeT::Root>, 129 | NodeT::Root, typename Right::Right> 130 | >::type; 131 | }; 132 | template 133 | struct Merge 134 | { 135 | using Root = typename std::conditional::value, Right, Left>::type; 136 | }; 137 | template 138 | using MergeT = typename Merge::Root; //为了使用起来更方便 139 | 140 | template 141 | struct Insert 142 | { 143 | const static int cur = stmp::next(); //这应该是VC++的bug,必须写出这个数来,不能直接在模板参数里用next() 144 | using T = typename Tree::ValueType; 145 | using SplitResult = Split; 146 | using NewNode = NodeT::value, NullT, NullT>; 147 | using Root = MergeT, typename SplitResult::Right>; 148 | }; 149 | template 150 | using InsertT = typename Insert::Root; 151 | 152 | template 153 | struct MakeTree; 154 | template 155 | struct MakeTree 156 | { 157 | using Root = InsertT::Root, First>; 158 | }; 159 | template 160 | struct MakeTree { using Root = NullT; }; 161 | template 162 | using MakeTreeT = typename MakeTree::Root; 163 | 164 | template 165 | struct Erase 166 | { 167 | using Result1 = Split; 168 | using Result2 = Split; 169 | using X = typename Result2::Left; //全部; //去掉一个==elem的 171 | using Z = typename Result1::Right; //全部>elem 172 | using Root = MergeT, Z>; 173 | }; 174 | template 175 | using EraseT = typename Erase::Root; 176 | } -------------------------------------------------------------------------------- /toy/legacy/vEBTree-pointer.h: -------------------------------------------------------------------------------- 1 | //Deprecated,用模板的才是真正的vEB 2 | /*#pragma once 3 | #include 4 | #include 5 | 6 | namespace ds 7 | { 8 | template //最终vEB树的容量是2^Size 9 | class vEBTree 10 | { 11 | public: 12 | static int countZero(int i) //返回一个形如0...010..0的数右侧的0的个数 13 | { 14 | 15 | #if __GNUC__ 16 | //gcc内置 17 | return __builtin_ctz(i); 18 | #else 19 | int cnt = 0; 20 | while (i >>= 1) 21 | ++cnt; 22 | return cnt; 23 | #endif 24 | 25 | 26 | } 27 | 28 | 要实现vEB Map有点困难(应该不是C++的锅) 29 | 每个节点的min都会配一个value,summary不用配value,size=2的节点需要两个value 30 | 要么统一配两个(浪费空间),要么用指针(浪费空间&时间),要么用模板 31 | 模板的大致思路是,首先处理Node*的函数都改成模板 32 | 然后size不同的Node,summary的Node都做成不同类型 33 | template 34 | struct Node { Node*summary ,Node cluster[lo(N)] } //hi和lo都是带N的常量表达式 35 | template 36 | struct Node<1,IsSummary> {...} 37 | template 38 | struct Node {...} 39 | 我也不知道这样写行不行,懒得试了 40 | 41 | struct Node 42 | { 43 | static int hiSqrt[32], loSqrt[32]; 44 | int zeros = 1; 45 | int min = -1; 46 | int max = -1; 47 | Node *summary = nullptr; 48 | Node **clusters = nullptr; 49 | //cluster是hi棵vEB树(大小为lo),summary是1棵vEB树(大小为hi) 50 | //cluster[i]不为空 <=> cluster[i]->min!=-1 <=> exist(summary,i)==true 51 | //元素x以lo(x)的形式存在clustre[hi(x)]中,但min元素并不储存在cluster中 52 | Node() = default; 53 | Node(int zeros, Node *summary, Node **clusters) :zeros(zeros), summary(summary), clusters(clusters) {} 54 | //编译器的确很聪明,但是我还是不太信任它,除/模变量恐怕很难优化 55 | int highPart(int x) const { return x >> (zeros >> 1); } 56 | int lowPart(int x) const { return x & (loSqrt[zeros] - 1); } 57 | int numOf(int hi, int lo) const { return (hi << (zeros >> 1)) + lo; } 58 | }; 59 | static Node* buildTree(int u) 60 | { 61 | if (u == 1) 62 | return new Node(); 63 | const int hi = Node::hiSqrt[u], lo = Node::loSqrt[u]; 64 | Node *summary = buildTree(countZero(hi)); 65 | Node **clusters = new Node*[hi]; 66 | for (int i = 0; i < hi; ++i) 67 | clusters[i] = buildTree(countZero(lo)); 68 | return new Node(u, summary, clusters); 69 | } 70 | Node *root; 71 | static int findMin(Node *z) 72 | { 73 | return z->min; 74 | } 75 | static int findMax(Node *z) 76 | { 77 | return z->max; 78 | } 79 | static void putOnEmpty(Node *z, int x) 80 | { 81 | z->min = z->max = x; 82 | } 83 | void insert(Node *z, int x) 84 | { 85 | if (z->min == -1) //min为-1意味着max也为-1,空节点直接插 86 | putOnEmpty(z, x); 87 | else 88 | { 89 | if (x < z->min) 90 | std::swap(x, z->min); 91 | if (z->zeros > 1) 92 | { 93 | const int hi = z->highPart(x), lo = z->lowPart(x); 94 | if (findMin(z->clusters[hi]) == -1) 95 | { 96 | insert(z->summary, z->highPart(x));//本簇中没有元素,需要修改summary 97 | putOnEmpty(z->clusters[hi], lo); 98 | } 99 | else //本簇中有元素 100 | insert(z->clusters[hi], lo); 101 | } 102 | if (z->max < x) //insert完了之后才修改,如果要改循环,需要独立出去 103 | z->max = x; 104 | } 105 | } 106 | void erase(Node *z, int x) 107 | { 108 | if (z->max == z->min) //有且只有一个元素 109 | z->max = z->min = -1; 110 | else if (z->zeros == 1) //两个元素,执行到这里x只能为0/1 111 | z->max = z->min = !x; 112 | else 113 | { 114 | if (x == z->min) //在簇中找一个元素来当新min 115 | { 116 | const int firstCluster = findMin(z->summary); //第一个非空的簇 117 | x = z->numOf(firstCluster, findMin(z->clusters[firstCluster])); //那个簇中的第一个元素 118 | z->min = x; 119 | } 120 | erase(z->clusters[z->highPart(x)], z->lowPart(x)); 121 | //以上完成了对簇的修改,以下解决簇为空之后的summary和维护max 122 | if (findMin(z->clusters[z->highPart(x)]) == -1) //刚删完的簇变空了 123 | { 124 | erase(z->summary, z->highPart(x)); 125 | if (x == z->max) //删掉的是max,需更新之;对于min的处理在上面; 126 | { 127 | const int maxSummary = findMax(z->summary); //由于用到了summary,对max的维护放在对summary的维护之后 128 | if (maxSummary == -1) 129 | z->max = z->min; 130 | else z->max = z->numOf(maxSummary, findMax(z->clusters[maxSummary])); 131 | } 132 | } 133 | else if (x == z->max) 134 | z->max = z->numOf(z->highPart(x), findMax(z->clusters[z->highPart(x)])); 135 | } 136 | } 137 | int findNext(Node *z, int x) 138 | { 139 | if (z->zeros == 1) 140 | return (x == 0 && z->max == 1) ? 1 : -1; 141 | if (x < z->min) //无需判断z->min是不是-1 142 | return z->min; 143 | const int inClusterMax = findMax(z->clusters[z->highPart(x)]); 144 | if (inClusterMax != -1 && z->lowPart(x)numOf(z->highPart(x), findNext(z->clusters[z->highPart(x)], z->lowPart(x))); 146 | const int nextCluster = findNext(z->summary, z->highPart(x)); //next不在当前簇 147 | if (nextCluster == -1) 148 | return -1; 149 | return z->numOf(nextCluster, findMin(z->clusters[nextCluster])); 150 | } 151 | int findPrev(Node *z, int x) 152 | { 153 | if (z->zeros == 1) 154 | return (x == 1 && z->min == 0) ? 0 : -1; 155 | if (z->max < x) //无需判断z->max是不是-1 156 | return z->max; 157 | const int clusterMin = findMin(z->clusters[z->highPart(x)]); 158 | if (clusterMin != -1 && clusterMin < z->lowPart(x)) 159 | return z->numOf(z->highPart(x), findPrev(z->clusters[z->highPart(x)], z->lowPart(x))); 160 | const int prevCluster = findPrev(z->summary, z->highPart(x)); 161 | if (prevCluster == -1) //z->min并不存在于cluster中,要特判 162 | return z->min < x ? z->min : -1; //无需判断z->min是不是-1 163 | return z->numOf(prevCluster, findMax(z->clusters[prevCluster])); 164 | } 165 | 166 | public: 167 | vEBTree() 168 | { 169 | for (int i = 0; i < 32; ++i) 170 | { 171 | Node::loSqrt[i] = 1 << (i >> 1); 172 | Node::hiSqrt[i] = 1 << ((i & 1) ? ((i + 1) >> 1) : (i >> 1)); 173 | } 174 | root = buildTree(Size); 175 | } 176 | int findMin() const 177 | { 178 | return root->min; 179 | } 180 | int findMax() const 181 | { 182 | return root->max; 183 | } 184 | bool exist(int x) const 185 | { 186 | Node *z = root; 187 | while (true) 188 | { 189 | if (z->min == x || z->max == x) 190 | return true; 191 | if (z->zeros == 1) 192 | return false; 193 | const int tmp = x; 194 | x = z->lowPart(x), z = z->clusters[z->highPart(tmp)]; 195 | } 196 | } 197 | void insert(int x, bool existed = false) //如果可以提供额外的信息(某个键一定存在/不存在),则可省去判断 198 | { 199 | if (!existed || !exist(x)) 200 | insert(root, x); 201 | } 202 | void erase(int x, bool existed = true) 203 | { 204 | if (existed || exist(x)) 205 | erase(root, x); 206 | } 207 | int findNext(int x) { return findNext(root, x); } 208 | int findPrev(int x) { return findPrev(root, x); } 209 | }; 210 | template 211 | int vEBTree::Node::hiSqrt[32]; 212 | template 213 | int vEBTree::Node::loSqrt[32]; 214 | }*/ 215 | -------------------------------------------------------------------------------- /integer/UInt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "BigInt.h" 5 | 6 | namespace ds 7 | { 8 | template 9 | class UInt 10 | { 11 | static_assert(Bit >= 32 && Bit % 32 == 0, "Bit illegal"); 12 | constexpr static int ArrLen = Bit / 32; 13 | uint32_t val[ArrLen]; 14 | static int comp(const UInt &lhs,const UInt &rhs) 15 | { 16 | for (int i = ArrLen - 1; i >= 0; --i) 17 | if (lhs[i] != rhs[i]) 18 | return lhs[i] < rhs[i] ? -1 : 1; 19 | return 0; 20 | } 21 | int hiBit() const 22 | { 23 | for (int i = ArrLen - 1; i >= 0; --i) 24 | if (val[i]) 25 | { 26 | for (int bit = 31; bit > 0; --bit) 27 | if (val[i] & 1 << bit) 28 | return 32 * i + bit; 29 | return 32 * i; 30 | } 31 | return -1; 32 | } 33 | public: 34 | uint32_t &operator[](int index) { return val[index]; } 35 | uint32_t operator[](int index) const { return val[index]; } 36 | BigInt toBigInt() const 37 | { 38 | BigInt ret, cur = 1; 39 | for (int i = 0; i < ArrLen; ++i) 40 | ret += cur * BigInt(val[i]), cur *= 1ull << 32; 41 | return ret; 42 | } 43 | UInt(uint32_t i = 0) : val{} { val[0] = i; } 44 | UInt(uint64_t i): val{} 45 | { 46 | static_assert(Bit >= 64, "Bit too short"); 47 | val[0] = i & 0xffffffff, val[1] = i >> 32; 48 | } 49 | static UInt fromHex(const char *src) 50 | { 51 | UInt ret; 52 | for (int i = 0, sz = strlen(src); i < ArrLen; ++i) 53 | for (int j = 0; j < 8 && i * 8 + j < sz; ++j) 54 | { 55 | char ch = src[sz - i * 8 - j - 1]; 56 | ret.val[i] += (isdigit(ch) ? ch - '0' : ch - 'a' + 10) << (j * 4); 57 | } 58 | return ret; 59 | } 60 | const char *toHex() 61 | { 62 | static char hex[ArrLen * 8]; 63 | auto mask = [](uint32_t x, int shift) {return (x >> shift * 4) & 15; }; 64 | auto toChar = [](int x) {return x < 10 ? x + '0' : x - 10 + 'a'; }; 65 | for (int i = 0; i < ArrLen; ++i) 66 | for (int j = 0; j < 8; ++j) 67 | hex[i * 8 + j] = toChar(mask(val[i], j)); 68 | std::reverse(hex, hex + sizeof hex); 69 | return hex; 70 | } 71 | friend UInt operator+(UInt lhs, const UInt &rhs) { return lhs += rhs; } 72 | friend UInt operator-(UInt lhs, const UInt &rhs) { return lhs -= rhs; } 73 | friend UInt operator<<(UInt lhs, int rhs) { return lhs <<= rhs; } 74 | friend UInt operator>>(UInt lhs, int rhs) { return lhs >>= rhs; } 75 | friend UInt operator&(UInt lhs, int rhs) { return lhs &= rhs; } 76 | friend UInt operator|(UInt lhs, int rhs) { return lhs |= rhs; } 77 | friend UInt operator^(UInt lhs, int rhs) { return lhs ^= rhs; } 78 | UInt &operator*=(const UInt &rhs) { return *this = *this * rhs; } 79 | UInt &operator/=(const UInt &rhs) { return *this = *this / rhs; } 80 | UInt &operator+=(const UInt &rhs) 81 | { 82 | uint64_t carry = 0ull; 83 | for (int i = 0; i < ArrLen; ++i) 84 | { 85 | carry += (uint64_t)val[i] + rhs.val[i]; 86 | val[i] = carry & 0xffffffff; 87 | carry >>= 32; 88 | } 89 | return *this; 90 | } 91 | UInt &operator-=(const UInt &rhs) { return *this += -rhs; } 92 | UInt operator-() const 93 | { 94 | UInt ret(*this); 95 | for (int i = 0; i < ArrLen; ++i) 96 | ret.val[i] = ~ret.val[i]; 97 | return ++ret; 98 | } 99 | UInt &operator++() 100 | { 101 | for (int i = 0; i < ArrLen && !++val[i++];); 102 | return *this; 103 | } 104 | UInt operator++(int) { UInt ret(this); return ++ret; } 105 | UInt &operator--() 106 | { 107 | for (int i = 0; i < ArrLen && !~--val[i++];); 108 | return *this; 109 | } 110 | UInt operator--(int) { UInt ret(this); return --ret; } 111 | UInt operator~() const 112 | { 113 | UInt ret(*this); 114 | for (int i = 0; i < ArrLen; ++i) 115 | ret[i] = ~ret[i]; 116 | return ret; 117 | } 118 | UInt &operator&=(const UInt &rhs) 119 | { 120 | for (int i = 0; i < ArrLen; ++i) 121 | val[i] &= rhs[i]; 122 | return *this; 123 | } 124 | UInt &operator|=(const UInt &rhs) 125 | { 126 | for (int i = 0; i < ArrLen; ++i) 127 | val[i] |= rhs[i]; 128 | return *this; 129 | } 130 | UInt &operator^=(const UInt &rhs) 131 | { 132 | for (int i = 0; i < ArrLen; ++i) 133 | val[i] ^= rhs[i]; 134 | return *this; 135 | } 136 | UInt &operator<<=(int shift) 137 | { 138 | const int wordShift = shift / 32; 139 | if (wordShift != 0) 140 | for (int pos = ArrLen - 1; pos >= 0; --pos) 141 | val[pos] = wordShift <= pos ? val[pos - wordShift] : 0; 142 | if ((shift %= 32) != 0) 143 | { 144 | for (int pos = ArrLen - 1; pos > 0; --pos) 145 | val[pos] = (val[pos] << shift) | (val[pos - 1] >> (32 - shift)); 146 | val[0] <<= shift; 147 | } 148 | return *this; 149 | } 150 | UInt &operator>>=(int shift) 151 | { 152 | const int wordShift = shift / 32; 153 | if (wordShift != 0) 154 | for (int pos = 0; pos < ArrLen; ++pos) 155 | val[pos] = wordShift < ArrLen - pos ? val[pos + wordShift] : 0; 156 | if ((shift %= 32) != 0) 157 | { 158 | for (int pos = 0; pos < ArrLen - 1; ++pos) 159 | val[pos] = (val[pos] >> shift) | (val[pos + 1] << (32 - shift)); 160 | val[ArrLen - 1] >>= shift; 161 | } 162 | return *this; 163 | } 164 | friend UInt operator*(const UInt &lhs,const UInt &rhs) 165 | { 166 | UInt ret; 167 | for (int i = 0; i < ArrLen; ++i) 168 | { 169 | uint64_t carry = 0; 170 | for (int j = 0; j + i < ArrLen; ++j) 171 | { 172 | uint64_t n = carry + ret[j + i] + (uint64_t)lhs[i] * rhs[j]; 173 | ret[j + i] = n & 0xffffffff; 174 | carry = n >> 32; 175 | } 176 | } 177 | return ret; 178 | } 179 | friend UInt operator/(UInt lhs, UInt rhs) //复制是一定要进行的,不如直接在参数中复制 180 | { 181 | UInt ret; 182 | int lhsBit = lhs.hiBit(), rhsBit = rhs.hiBit(); 183 | if (rhsBit > lhsBit) 184 | return 0u; 185 | int shift = lhsBit - rhsBit; 186 | rhs <<= shift; 187 | while (shift >= 0) //思路:分别考虑每个二进制位填1还是0 188 | { 189 | if (lhs >= rhs) 190 | { 191 | lhs -= rhs; //填1意味着需要一个rhs,那么lhs就减掉一个rhs 192 | ret[shift / 32] |= 1 << (shift % 32); //填上一个1 193 | } 194 | rhs >>= 1; //rhs除2后继续考虑 195 | --shift; 196 | } 197 | return ret; 198 | } 199 | bool operator<(const UInt &rhs)const { return comp(*this, rhs) < 0; } 200 | bool operator<=(const UInt &rhs)const { return comp(*this, rhs) <= 0; } 201 | bool operator>(const UInt &rhs)const { return comp(*this, rhs) > 0; } 202 | bool operator>=(const UInt &rhs)const { return comp(*this, rhs) >= 0; } 203 | bool operator==(const UInt &rhs)const { return comp(*this, rhs) == 0; } 204 | bool operator!=(const UInt &rhs)const { return comp(*this, rhs) != 0; } 205 | explicit operator bool() const 206 | { 207 | uint32_t ret = 0; 208 | for (int i = 0; i < ArrLen; ++i) 209 | ret |= val[i]; 210 | return ret != 0; 211 | } 212 | }; 213 | } 214 | -------------------------------------------------------------------------------- /toy/Calculator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Util.h" 3 | 4 | namespace ds 5 | { 6 | class Calculator 7 | { 8 | private: 9 | typedef std::pair ResPair; 10 | class Node 11 | { 12 | Node *left = nullptr; 13 | Node *right = nullptr; 14 | char opt = 0; 15 | friend Calculator; 16 | public: 17 | double val = 0.0; 18 | double dval = 0.0; 19 | Node &operator=(const ResPair &rhs) 20 | { 21 | val = rhs.first; 22 | dval = rhs.second; 23 | return *this; 24 | } 25 | static ResPair plus(const Node &lhs ,const Node &rhs) { return { lhs.val + rhs.val,lhs.dval + rhs.dval }; } 26 | static ResPair minus(const Node &lhs, const Node &rhs) { return { lhs.val - rhs.val,lhs.dval - rhs.dval }; } 27 | static ResPair multiplies(const Node &lhs, const Node &rhs) { return { lhs.val * rhs.val,lhs.dval * rhs.val + lhs.val * rhs.dval }; } 28 | static ResPair divides(const Node &lhs, const Node &rhs) { return { lhs.val / rhs.val,(lhs.dval * rhs.val - lhs.val * rhs.dval) / (rhs.val*rhs.val) }; } 29 | static ResPair pow(const Node &lhs, const Node &rhs) 30 | { 31 | //(u^v)' = (e^(v*lnu))' = (v*1/u*u' + v'*lnu)*(u^v) 32 | double ans = std::pow(lhs.val, rhs.val); 33 | double d = (rhs.val / lhs.val * lhs.dval + rhs.dval * std::log(lhs.val)) * ans; 34 | return { ans,d }; 35 | } 36 | //为了配合二元函数表,这里sin之类的也做成二元函数,sin(x) := 0 s x 37 | static ResPair sin(const Node &, const Node &rhs) { return { std::sin(rhs.val),std::cos(rhs.val) * rhs.dval }; } 38 | static ResPair cos(const Node &, const Node &rhs) { return { std::cos(rhs.val),-std::sin(rhs.val) * rhs.dval }; } 39 | static ResPair ln(const Node &, const Node &rhs) { return { std::log(rhs.val),1 / rhs.val * rhs.dval }; } 40 | }; 41 | public: 42 | //The type of the lambda-expression (which is also the type of the closure object) 43 | //is a unique, unnamed non-union class type 44 | //每一个lambda表达式都有独一无二的类型,妄想这样利用容器保存lambda是不可能的 45 | //错误示例:typedef decltype([](double, double) {return 0.0; }) Calc; 46 | //但是(没有捕获变量的)lambda可以隐式转化为函数指针,这样还是可以避开sdt::function 47 | using Calc = double(*)(double, double); 48 | typedef std::array Table; 49 | using Der = decltype(&Node::plus); 50 | typedef std::array DerTable; 51 | typedef std::array PriTable; 52 | private: 53 | Node *root = nullptr; 54 | static Node *dummy; //可以减少一些边界检查 55 | static Table table; 56 | static DerTable dtable; 57 | static PriTable ptable; 58 | static Table buildTable() 59 | { 60 | Table tmp; 61 | tmp['+'] = [](double a, double b) {return a + b; }; 62 | tmp['-'] = [](double a, double b) {return a - b; }; 63 | tmp['*'] = [](double a, double b) {return a * b; }; 64 | tmp['/'] = [](double a, double b) {return a / b; }; 65 | tmp['^'] = std::pow; //强迫症福利 66 | tmp['s'] = [](double, double x) {return std::sin(x); }; 67 | tmp['c'] = [](double, double x) {return std::cos(x); }; 68 | tmp['l'] = [](double, double x) {return std::log(x); }; 69 | return tmp; 70 | } 71 | 72 | static DerTable buildDTable() 73 | { 74 | DerTable tmp; 75 | tmp['+'] = &Node::plus, tmp['-'] = &Node::minus, tmp['*'] = &Node::multiplies, tmp['/'] = &Node::divides, tmp['^'] = &Node::pow; 76 | tmp['s'] = &Node::sin, tmp['c'] = &Node::cos, tmp['l'] = &Node::ln; 77 | return tmp; 78 | } 79 | static PriTable buildPTable() 80 | { 81 | PriTable tmp; 82 | memset(&tmp[0], 0, sizeof tmp); //再次提醒:内置类型的std::array不会初始化 83 | tmp['+'] = tmp['-'] = 1; 84 | tmp['*'] = tmp['/'] = 2; 85 | tmp['s'] = tmp['c'] = tmp['l'] = 3; //认为sinx^2表示sin(x^2) 86 | tmp['^'] = 4; 87 | return tmp; 88 | } 89 | static Node* build(const std::string& s, int beg, int end) 90 | { 91 | if (beg >= end) 92 | return dummy; 93 | bool isVal = true; //是否只含数字或者变量 94 | int pos[127]; //不在任何括号内的 不同优先级的 运算符的 最后一次出现的位置 95 | memset(pos, -1, sizeof pos); 96 | int cnt = 0; 97 | for (int i = beg; i < end; ++i) 98 | { 99 | if (s[i] == '(') ++cnt, isVal = false; 100 | if (s[i] == ')') --cnt, isVal = false; 101 | if (!cnt && ptable[s[i]]) pos[ptable[s[i]]] = i, isVal = false; 102 | } 103 | if (isVal) 104 | { 105 | Node *n = new Node; 106 | if (s[beg] == 'x') n->opt = 'x'; 107 | else n->val = atof(s.c_str() + beg); 108 | return n; 109 | } 110 | //优先级最低的运算符最后一次出现的位置,便是整个表达式最后一次进行的运算 111 | int *lastOpt = std::find_if(std::begin(pos), std::end(pos), [](int x) {return x != -1; }); 112 | if (lastOpt == std::end(pos)) //表达式形如(exp) 113 | return build(s, beg + 1, end - 1); 114 | Node *n = new Node; 115 | n->opt = s[*lastOpt]; 116 | n->left = build(s, beg, *lastOpt); 117 | n->right = build(s, *lastOpt + 1, end); 118 | return n; 119 | } 120 | static double result(const Node *n, double x) 121 | { 122 | if (!n) return 0.0; 123 | if (!n->left && !n->right) return n->opt == 'x' ? x : n->val; 124 | return table[n->opt](result(n->left, x), result(n->right, x)); 125 | } 126 | static void derivative(Node *n, double x) 127 | { 128 | if (!n) return; 129 | if (!n->left && !n->right) //叶子结点只有存了变量导数才是1 130 | { 131 | if (n->opt == 'x') n->val = x, n->dval = 1.0; 132 | return; 133 | } 134 | derivative(n->left, x); 135 | derivative(n->right, x); 136 | *n = dtable[n->opt](*n->left, *n->right); 137 | } 138 | static void clear(Node *x) 139 | { 140 | if (!x) 141 | return; 142 | clear(x->left); 143 | clear(x->right); 144 | if (x != dummy) 145 | delete x; 146 | } 147 | public: 148 | Calculator(std::string s) 149 | { 150 | auto replace = [](std::string &raw, const std::string &o, const std::string &n) -> void 151 | { 152 | int p = 0; 153 | while ((p = raw.find(o, p)) != std::string::npos) 154 | { 155 | raw.replace(p, o.size(), n); 156 | p += static_cast(n.size()) - static_cast(o.size()) + 1; 157 | } 158 | }; 159 | replace(s, "sin", "s"); 160 | replace(s, "cos", "c"); 161 | replace(s, "ln", "l"); 162 | replace(s, " ", ""); 163 | root = build(s, 0, s.size()); 164 | } 165 | Calculator(const Calculator &) = delete; 166 | Calculator& operator=(const Calculator &) = delete; 167 | ~Calculator() { clear(root); } 168 | 169 | double result(double x = 0.0) const 170 | { 171 | return result(root, x); 172 | } 173 | double derivative(double x) const 174 | { 175 | derivative(root, x); 176 | return root->dval; 177 | } 178 | double solve(double goal, double hint, double eps = 1e-5) const 179 | { 180 | double x = hint; 181 | while (derivative(root, x), std::fabs(root->val - goal) > eps) 182 | x -= (root->val - goal) / root->dval; 183 | return x; 184 | } 185 | }; 186 | Calculator::Table Calculator::table = buildTable(); 187 | Calculator::DerTable Calculator::dtable = buildDTable(); 188 | Calculator::PriTable Calculator::ptable = buildPTable(); 189 | Calculator::Node *Calculator::dummy = new Node; 190 | } 191 | -------------------------------------------------------------------------------- /toy/Polynomial.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ds 9 | { 10 | class Polynomial : public std::vector 11 | { 12 | constexpr static double eps = 1e-5; 13 | 14 | void trim() 15 | { 16 | while (!empty() && fabs(back()) < eps) 17 | pop_back(); 18 | } 19 | 20 | public: 21 | template 22 | friend OS &&operator<<(OS &&os, const Polynomial &p) 23 | { 24 | if (p.empty()) 25 | return os << "0"; 26 | for (auto it = p.rbegin(); it != p.rend(); ++it) 27 | os << *it << ' '; 28 | return os; 29 | } 30 | 31 | explicit Polynomial(int size, double value = 0.0) : vector(size, value) 32 | {} 33 | 34 | Polynomial(std::initializer_list lst) : vector(lst) 35 | { std::reverse(begin(), end()); } 36 | 37 | Polynomial &operator+=(const Polynomial &rhs) 38 | { 39 | const int cap = std::max(size(), rhs.size()); 40 | resize(cap); 41 | for (int i = 0; i < cap; ++i) 42 | (*this)[i] += i > rhs.size() ? 0 : rhs[i]; 43 | trim(); 44 | return *this; 45 | } 46 | 47 | friend Polynomial operator+(Polynomial lhs, const Polynomial &rhs) 48 | { return lhs += rhs; } 49 | 50 | Polynomial &operator-=(const Polynomial &rhs) 51 | { 52 | const int cap = std::max(size(), rhs.size()); 53 | resize(cap); 54 | for (int i = 0; i < cap; ++i) 55 | (*this)[i] -= i > rhs.size() ? 0 : rhs[i]; 56 | trim(); 57 | return *this; 58 | } 59 | 60 | friend Polynomial operator-(Polynomial lhs, const Polynomial &rhs) 61 | { return lhs -= rhs; } 62 | 63 | Polynomial &operator*=(double rhs) 64 | { 65 | for (auto &d:*this) 66 | d *= rhs; 67 | return *this; 68 | } 69 | 70 | friend Polynomial operator*(Polynomial lhs, double rhs) 71 | { return lhs *= rhs; } 72 | 73 | friend Polynomial operator*(double lhs, Polynomial rhs) 74 | { return rhs *= lhs; } 75 | 76 | friend Polynomial operator*(const Polynomial &lhs, const Polynomial &rhs) 77 | { 78 | const int lSize = lhs.size(), rSize = rhs.size(); 79 | Polynomial ret(lSize + rSize - 1); 80 | for (int i = 0; i < lSize; ++i) 81 | for (int j = 0; j < rSize; ++j) 82 | ret[i + j] += lhs[i] * rhs[j]; 83 | ret.trim(); 84 | return ret; 85 | } 86 | 87 | Polynomial &operator*=(const Polynomial &rhs) 88 | { return *this = *this * rhs; } 89 | 90 | //除法无法原地操作,所以用/来实现/= 91 | Polynomial &operator/=(const Polynomial &rhs) 92 | { return *this = *this / rhs; } 93 | 94 | friend Polynomial operator/(Polynomial lhs, const Polynomial &rhs) 95 | { 96 | if (lhs.size() < rhs.size()) 97 | return {}; 98 | Polynomial ret(lhs.size()); 99 | while (lhs.size() >= rhs.size()) 100 | { 101 | const double fac = lhs.back() / rhs.back(); 102 | auto it1 = lhs.rbegin(); 103 | auto it2 = rhs.rbegin(); 104 | for (; it1 != lhs.rend(); ++it1, ++it2) 105 | *it1 -= fac * *it2; 106 | ret[lhs.size() - rhs.size()] = fac; 107 | lhs.trim(); 108 | } 109 | ret.trim(); 110 | return ret; 111 | } 112 | 113 | Polynomial &operator%=(const Polynomial &rhs) 114 | { 115 | if (size() < rhs.size()) 116 | return *this; 117 | while (size() >= rhs.size()) 118 | { 119 | const double fac = back() / rhs.back(); 120 | auto it1 = rbegin(); 121 | auto it2 = rhs.rbegin(); 122 | for (; it1 != rend(); ++it1, ++it2) 123 | *it1 -= fac * *it2; 124 | trim(); 125 | } 126 | return *this; 127 | } 128 | 129 | friend Polynomial operator%(Polynomial lhs, const Polynomial &rhs) 130 | { return lhs %= rhs; } 131 | 132 | explicit operator bool() const 133 | { return !empty(); } 134 | 135 | }; 136 | 137 | inline Polynomial gcd(const Polynomial &lhs, const Polynomial &rhs) 138 | { return rhs ? gcd(rhs, lhs % rhs) : lhs; } 139 | 140 | inline Polynomial pow(Polynomial lhs, int rhs) 141 | { 142 | --rhs; 143 | Polynomial ret = lhs; 144 | while (rhs) 145 | { 146 | if (rhs & 1) 147 | ret *= lhs; 148 | lhs *= lhs; 149 | rhs >>= 1; 150 | } 151 | return ret; 152 | } 153 | 154 | 155 | // template 156 | // class Polynomial : public std::vector 157 | // { 158 | // public: 159 | // Polynomial &operator+=(const Polynomial &rhs) 160 | // { 161 | // if (rhs.size() > size()) 162 | // resize(rhs.size()); 163 | // for (int i = 0; i < size(); ++i) 164 | // operator[](i) += i >= rhs.size() ? Number() : rhs[i]; 165 | // return *this; 166 | // } 167 | // Polynomial operator-() const 168 | // { 169 | // Polynomial ret(*this); 170 | // for (int i = 0; i < ret.size(); ++i) 171 | // ret[i] = -ret[i]; 172 | // return ret; 173 | // } 174 | // Polynomial &operator-=(const Polynomial &rhs) 175 | // { 176 | // return operator+=(-rhs); 177 | // } 178 | // Polynomial &operator*=(const Polynomial &rhs) 179 | // { 180 | // int nSize = size() + rhs.size(); 181 | // int lg = 0; 182 | // for (; 1 << lg < nSize; lg <<= 1); 183 | // nSize = 1 << lg; 184 | // Polynomial a(nSize), b(nSize); 185 | // for (int i = 0; i < size(); ++i) 186 | // a[i].x = operator[](i); 187 | // for (int i = 0; i < rhs.size(); ++i) 188 | // b[i].x = rhs[i]; 189 | // fft(a, 1); 190 | // fft(b, 1); 191 | // for (int i = 0; i < a.size(); ++i) 192 | // a[i] *= b[i]; 193 | // fft(a, -1); 194 | // resize(a.size()); 195 | // for (int i = 0; i < size(); ++i) 196 | // operator[](i) = a[i].x; 197 | // return *this; 198 | // } 199 | // private: 200 | // struct Complex 201 | // { 202 | // double x, y; 203 | // Complex operator*(const Complex&rhs) const { return { x*rhs.x - y*rhs.y, x*rhs.y + y*rhs.x }; } 204 | // Complex operator+(const Complex&rhs) const { return { x + rhs.x, y + rhs.y }; } 205 | // Complex operator-(const Complex&rhs) const { return { x - rhs.x, y - rhs.y }; } 206 | // }; 207 | // static void bitReverse(Polynomial &in) 208 | // { 209 | // //把每个下标的二进制表示反转(只反转0-lgn位)之后得到新的下标 210 | // //这样可以把递归树构建出来 211 | // for (int i = 0, j = 0; i < in.size(); ++i) 212 | // { 213 | // if (i > j) 214 | // std::swap(in[i], in[j]); 215 | // for (int l = in.size() >> 1; (j ^= l) < l; l >>= 1); 216 | // } 217 | // } 218 | // //f==1把系数表示转换成点值表示,f==-1把点值表示转换成系数表示 219 | // static void fft(Polynomial &in,int f) 220 | // { 221 | // const static double pi = acos(-1); 222 | // bitReverse(in); 223 | // for (int i = 1; i < in.size(); i <<= 1) { 224 | // Complex wn{ cos(pi / i), f * sin(pi / i) }; 225 | // for (int j = 0; j < in.size(); j += (i << 1)) 226 | // { 227 | // Complex w{ 1.0, 0.0 }; 228 | // for (int k = 0; k < i; ++k, w *= wn) 229 | // { 230 | // Complex x = in[j + k], y = w * in[j + k + i]; 231 | // in[j + k] = x + y; 232 | // in[j + k + i] = x - y; 233 | // } 234 | // } 235 | // } 236 | // if (f == -1) 237 | // for (int i = 0; i < in.size(); ++i) 238 | // in[i].x /= in.size(); 239 | // } 240 | // 241 | // }; 242 | } -------------------------------------------------------------------------------- /toy/template/ListT.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ds 5 | { 6 | template 7 | struct NullT 8 | { 9 | //NullT相当于空指针,空指针显然也可以有自己的类型 10 | typedef T ValueType; 11 | }; 12 | template 13 | struct IsNull //有些返回值不是NullT,而是继承自NullT,所以这里加一个判断 14 | { 15 | const static bool value = std::is_base_of, T>::value; 16 | }; 17 | 18 | template 19 | struct ListT; 20 | 21 | template 22 | struct ListT 23 | { 24 | typedef ListT Next; 25 | const static T value = First; 26 | typedef T ValueType; 27 | }; 28 | 29 | template 30 | struct ListT 31 | { 32 | typedef NullT Next; 33 | const static T value = First; 34 | typedef T ValueType; 35 | }; 36 | 37 | template 38 | struct Get : Get 39 | { }; 40 | template 41 | struct Get : List 42 | { }; 43 | 44 | template 46 | struct Find : Find 47 | { }; 48 | template 49 | struct Find 50 | { 51 | const static int value = Where; 52 | }; 53 | 54 | namespace outimpl 55 | { 56 | //之所以把它放在外面,是为了使编译器输出更简洁一点 57 | template 58 | struct Impl; //利用编译器的错误信息来输出 59 | } 60 | template ::value> 61 | struct Output 62 | { 63 | outimpl::Impl impl{}; //貌似不加大括号强制初始化的话,输出的顺序就会乱,不知道为什么 64 | Output next; 65 | }; 66 | template 67 | struct Output 68 | { }; 69 | 70 | template ::value> 71 | struct Size 72 | { 73 | const static int value = Size::value + 1; 74 | }; 75 | template 76 | struct Size 77 | { 78 | const static int value = 0; 79 | }; 80 | 81 | template 82 | struct PushFront 83 | { 84 | typedef List Next; 85 | const static typename List::ValueType value = Elem; 86 | typedef typename List::ValueType ValueType; 87 | }; 88 | 89 | namespace pbimpl 90 | { 91 | template ::value> 92 | struct Impl 93 | { 94 | typedef Impl Next; 95 | const static T value = Iter::value; 96 | typedef T ValueType; 97 | }; 98 | template 99 | struct Impl 100 | { 101 | const static T value = Elem; 102 | typedef NullT Next; 103 | typedef T ValueType; 104 | }; 105 | } 106 | template 107 | struct PushBack : pbimpl::Impl 108 | { }; 109 | 110 | namespace setimpl 111 | { 112 | template ::value> 113 | struct Impl : Impl< 114 | typename std::conditional, PushBack>::type, 115 | typename Iter::Next, Where - 1, Elem> 116 | { }; 117 | template 118 | struct Impl : Return 119 | { }; 120 | //如果where越界,按照上面的逻辑,会自动地不做任何处理 121 | } 122 | template 123 | struct Set : setimpl::Impl, List, Where, Elem> 124 | { }; 125 | 126 | namespace eraseimpl 127 | { 128 | template ::value> 129 | struct Impl : Impl< 130 | typename std::conditional, Return>::type, 131 | typename Iter::Next, Where - 1> 132 | { }; 133 | template 134 | struct Impl : Return 135 | { }; 136 | } 137 | template 138 | struct Erase : eraseimpl::Impl, List, Where> 139 | { }; 140 | 141 | namespace mapimpl 142 | { 143 | template class Pred, bool Null = IsNull::value> 144 | struct Impl : Impl::value>, typename Iter::Next, Pred> 145 | { }; 146 | template class Pred> 147 | struct Impl : Return 148 | { }; 149 | } 150 | template class Pred> 151 | struct Map : mapimpl::Impl, List, Pred> 152 | { }; 153 | 154 | namespace filimpl 155 | { 156 | template class Pred, bool Null = IsNull::value> 157 | struct Impl : Impl::value, PushBack, Return>::type, 159 | typename Iter::Next, Pred> 160 | { }; 161 | template class Pred> 162 | struct Impl : Return 163 | { }; 164 | } 165 | template class Pred> 166 | struct Filter : filimpl::Impl, List, Pred> 167 | { }; 168 | 169 | namespace conimpl 170 | { 171 | template ::value> 172 | struct Impl : Impl, typename L2::Next> 173 | { }; 174 | template 175 | struct Impl : L1 176 | { }; 177 | } 178 | template 179 | struct Contact : conimpl::Impl 180 | { }; 181 | 182 | namespace sortimpl 183 | { 184 | template ::value> 185 | struct Impl 186 | { 187 | using T = typename List::ValueType; 188 | const static T pivot = List::value; 189 | template 190 | struct Less { const static bool value = I < pivot; }; 191 | template 192 | struct Equal { const static bool value = I == pivot; }; 193 | template 194 | struct Greater { const static bool value = I > pivot; }; 195 | using L1 = Filter; 196 | using L2 = Filter; 197 | using L3 = Filter; 198 | using Type = Contact::Type, L2>, typename Impl::Type>; 199 | }; 200 | template 201 | struct Impl 202 | { 203 | using Type = List; 204 | }; 205 | } 206 | template 207 | struct Sort : sortimpl::Impl::Type 208 | { }; 209 | } -------------------------------------------------------------------------------- /integer/BigInt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace ds 8 | { 9 | class BigInt 10 | { 11 | //C风格的比较函数,其正负等于abs(lhs)-abs(rhs)的正负 12 | static int absComp(const BigInt &lhs, const BigInt &rhs) 13 | { 14 | if (lhs.size() != rhs.size()) 15 | return lhs.size() < rhs.size() ? -1 : 1; 16 | for (int i = lhs.size() - 1; i >= 0; --i) 17 | if (lhs[i] != rhs[i]) 18 | return lhs[i] < rhs[i] ? -1 : 1; 19 | return 0; 20 | } 21 | using Long = long long; 22 | const static int Exp = 9; 23 | const static Long Mod = 1000000000; 24 | mutable std::vector val; 25 | mutable bool nega = false; 26 | //规定:0的nega必须是false,0的size必须是0 27 | void trim() const 28 | { 29 | while (!val.empty() && val.back() == 0) 30 | val.pop_back(); 31 | if (val.empty()) 32 | nega = false; 33 | } 34 | int size() const { return val.size(); } 35 | Long &operator[](int index) const { return val[index]; } 36 | Long &back() const { return val.back(); } 37 | BigInt(int size, bool nega) : val(size), nega(nega) {} 38 | BigInt(const std::vector &val, bool nega) : val(val), nega(nega) {} 39 | 40 | public: 41 | friend std::ostream &operator<<(std::ostream &os, const BigInt &n) 42 | { 43 | if (n.size()) 44 | { 45 | if (n.nega) 46 | os << '-'; 47 | os << n.back(); 48 | for (int i = (int)n.size() - 2; i >= 0; --i) 49 | os << std::setw(n.Exp) << std::setfill('0') << n[i]; 50 | } 51 | else 52 | os << 0; 53 | return os; 54 | } 55 | friend BigInt operator+(const BigInt &lhs, const BigInt &rhs) 56 | { 57 | BigInt ret(lhs); 58 | return ret += rhs; 59 | } 60 | friend BigInt operator-(const BigInt &lhs, const BigInt &rhs) 61 | { 62 | BigInt ret(lhs); 63 | return ret -= rhs; 64 | } 65 | BigInt(Long x = 0) 66 | { 67 | if (x < 0) 68 | x = -x, nega = true; 69 | while (x >= Mod) 70 | val.push_back(x % Mod), x /= Mod; 71 | if (x) 72 | val.push_back(x); 73 | } 74 | BigInt(const char *s) 75 | { 76 | if (s[0] == '-') 77 | nega = true, ++s; 78 | int cur = 0, pow = 1, pos; //int存就够了 79 | for (pos = strlen(s) - 1; pos >= Exp - 1; pos -= Exp, val.push_back(cur), cur = 0, pow = 1) 80 | for (int i = pos; i > pos - Exp; --i) 81 | cur += (s[i] - '0') * pow, pow *= 10; 82 | for (cur = 0, pow = 1; pos >= 0; --pos) 83 | cur += (s[pos] - '0') * pow, pow *= 10; 84 | if (cur) 85 | val.push_back(cur); 86 | } 87 | BigInt &assign(const BigInt &rhs) //为了充分利用之前已经申请的空间 88 | { 89 | val.resize(rhs.size()); 90 | nega = rhs.nega; 91 | if (!val.empty()) 92 | memcpy(&val[0], &rhs[0], val.size() * sizeof(Long)); 93 | return *this; 94 | } 95 | BigInt &operator+=(const BigInt &rhs) 96 | { 97 | const int cap = std::max(size(), rhs.size()); 98 | val.resize(cap); 99 | int carry = 0; 100 | for (int i = 0; i < cap; ++i) 101 | { 102 | val[i] = (nega ? -val[i] : val[i]) + (i < rhs.size() ? (rhs.nega ? -rhs[i] : rhs[i]) : 0) + carry, carry = 0; 103 | if (val[i] >= Mod) 104 | val[i] -= Mod, carry = 1; //至多只需要减一次,不需要取模 105 | else while (val[i] < 0) //有可能需要加两次,例如-9-2 106 | val[i] += Mod, --carry; 107 | } 108 | nega = carry < 0; 109 | if (carry) 110 | { 111 | val.push_back(carry < 0 ? -carry : carry); 112 | if (nega) 113 | { 114 | carry = 0; 115 | for (int i = 0; i < cap; ++i) 116 | if (carry != 0 || val[i] != 0) 117 | val[i] = Mod + carry - val[i], carry = -1; 118 | val.back() += carry; 119 | } 120 | } 121 | trim(); 122 | return *this; 123 | } 124 | friend BigInt operator-(const BigInt &rhs) 125 | { 126 | BigInt ret(rhs); 127 | ret.nega ^= 1; 128 | return ret; 129 | } 130 | BigInt &operator-=(const BigInt &rhs) 131 | { 132 | rhs.nega ^= 1; 133 | *this += rhs; 134 | rhs.nega ^= 1; 135 | return *this; 136 | } 137 | //高精*高精没办法原地操作,所以实现operator*,除法同理 138 | friend BigInt operator*(const BigInt &lhs, const BigInt &rhs) 139 | { 140 | const int cap = lhs.size() + rhs.size() + 1; 141 | BigInt ret(cap, lhs.nega ^ rhs.nega); 142 | for (int i = 0; i < cap - 1; ++i) 143 | for (int j = std::max(i - rhs.size() + 1, 0), up = std::min(i + 1, lhs.size()); j < up; ++j) 144 | { 145 | ret[i] += lhs[j] * rhs[i - j]; 146 | ret[i + 1] += ret[i] / Mod, ret[i] %= Mod; 147 | } 148 | ret.trim(); 149 | return ret; 150 | } 151 | BigInt &operator*=(const BigInt &rhs) { return *this = *this * rhs; } 152 | friend BigInt operator/(const BigInt &lhs, const BigInt &rhs) 153 | { 154 | static std::vector powTwo{ BigInt(1) }; 155 | static std::vector estimate; 156 | estimate.clear(); 157 | if (absComp(lhs, rhs) < 0) 158 | return BigInt(); 159 | BigInt cur = rhs; 160 | int cmp; 161 | while ((cmp = absComp(cur, lhs)) <= 0) 162 | { 163 | estimate.push_back(cur), cur += cur; 164 | if (estimate.size() > powTwo.size()) 165 | powTwo.push_back(powTwo.back() + powTwo.back()); 166 | } 167 | if (cmp == 0) 168 | return BigInt(powTwo.back().val, lhs.nega ^ rhs.nega); 169 | const int begin = estimate.size() - 1; 170 | BigInt ret = powTwo[begin], tmp; 171 | cur = estimate[begin]; 172 | for (int i = begin; i >= 0 && cmp != 0; --i) 173 | if ((cmp = absComp(tmp.assign(cur) += estimate[i], lhs)) <= 0) 174 | cur.assign(tmp), ret += powTwo[i]; //运算过程中几乎不会发生内存申请 175 | ret.nega = lhs.nega ^ rhs.nega; 176 | return ret; 177 | } 178 | BigInt &operator/=(const BigInt &rhs) { return *this = *this / rhs; } 179 | friend BigInt operator/(const BigInt &lhs, int rhs) 180 | { 181 | BigInt ret(lhs.size(), lhs.nega ^ (rhs < 0)); 182 | if (rhs < 0) 183 | rhs = -rhs; 184 | Long carry = 0; 185 | for (int i = ret.size() - 1; i >= 0; --i) 186 | { 187 | carry = carry * lhs.Mod + lhs[i]; 188 | ret[i] = carry / rhs; 189 | carry %= rhs; 190 | } 191 | ret.trim(); 192 | return ret; 193 | } 194 | BigInt &operator/=(int rhs) { return *this = *this / rhs; } 195 | operator bool() const { return !val.empty(); } 196 | bool operator==(const BigInt &rhs) const { return nega == rhs.nega && val == rhs.val; } 197 | bool operator!=(const BigInt &rhs) const { return nega != rhs.nega || val != rhs.val; } 198 | bool operator>=(const BigInt &rhs) const { return !(*this < rhs); } 199 | bool operator>(const BigInt &rhs) const { return !(*this <= rhs); } 200 | bool operator<=(const BigInt &rhs) const 201 | { 202 | if (nega && !rhs.nega) 203 | return true; 204 | if (!nega && rhs.nega) 205 | return false; 206 | int cmp = absComp(*this, rhs); 207 | return nega ? cmp >= 0 : cmp <= 0; 208 | } 209 | bool operator<(const BigInt &rhs) const 210 | { 211 | if (nega && !rhs.nega) 212 | return true; 213 | if (!nega && rhs.nega) 214 | return false; 215 | return (absComp(*this, rhs) < 0) ^ nega; 216 | } 217 | void swap(const BigInt &rhs) const 218 | { 219 | std::swap(val, rhs.val); 220 | std::swap(nega, rhs.nega); 221 | } 222 | }; 223 | } 224 | -------------------------------------------------------------------------------- /sequential/Deque.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Algorithm.h" 3 | 4 | namespace ds 5 | { 6 | template 7 | class Deque 8 | { 9 | using Block = T *; 10 | const static int InitialCap = 16; 11 | Block *blocks = nullptr; //不采用循环队列,而是简单地从中间开始向两边拓展,毕竟扩容的代价是很小的 12 | int firstBlock = 0, lastBlock = 0; 13 | int blockCap = 0; 14 | int head = 0, tail = 0; 15 | //lastBlock指向past end元素所在的块,而非最后一个块之后的块 16 | //规定:tail==0当且仅当没有任何元素,这也将是empty函数的依据 17 | //只要有元素,tail的值必须在[1,BlockSize]之间 18 | template 19 | static P *alloc(int size) { return reinterpret_cast

(malloc(size * sizeof(P))); } 20 | template 21 | static void dealloc(P *ptr) { free(ptr); } 22 | template 23 | static void destroy(P *ptr,int first,int last) 24 | { 25 | if (!std::is_trivially_destructible

::value) 26 | for (P *cur = ptr + first, *end = ptr + last; cur != end; ++cur) 27 | cur->~P(); 28 | } 29 | template 30 | static void destroy(P *ptr) { ptr->~P(); } 31 | template 32 | static void construct(P *ptr, V &&value) { new(ptr) typename std::decay::type(std::forward(value)); } 33 | void expand() 34 | { 35 | Block *nBlocks = alloc(blockCap <<= 1); 36 | //int mid = (firstBlock + lastBlock) / 2; //把指针调整到新申请的内存的中间,这不是必要的操作,只是直觉上性能会好一些 37 | memcpy(nBlocks + firstBlock + blockCap / 4 , blocks + firstBlock, 38 | sizeof(Block) * (lastBlock - firstBlock + 1)); 39 | dealloc(blocks); 40 | blocks = nBlocks; 41 | firstBlock += blockCap / 4 , lastBlock += blockCap / 4; 42 | } 43 | 44 | public: 45 | Deque() 46 | { 47 | blocks = alloc(blockCap = InitialCap); 48 | firstBlock = lastBlock = blockCap / 2; 49 | blocks[firstBlock] = alloc(BlockSize); 50 | } 51 | void swap(Deque &other) noexcept { ds::bitwiseSwap(this, &other); } 52 | Deque(const Deque &src) 53 | { 54 | blocks = alloc(blockCap = src.blockCap); 55 | firstBlock = src.firstBlock, lastBlock = src.lastBlock; 56 | head = src.head, tail = src.tail; 57 | for (int i = firstBlock; i <= lastBlock; ++i) 58 | { 59 | blocks[i] = alloc(BlockSize); 60 | for (int j = (i == firstBlock ? head : 0); j < (i == lastBlock ? tail : BlockSize); ++j) 61 | construct(&blocks[i][j], src.blocks[i][j]); 62 | } 63 | } 64 | Deque(Deque &&src) noexcept 65 | { 66 | memcpy(this, &src, sizeof(Deque)); 67 | memset(&src, 0, sizeof(Deque)); 68 | } 69 | Deque &operator=(const Deque &src) 70 | { 71 | if (this != &src) 72 | { 73 | Deque tmp(src); 74 | swap(tmp); 75 | } 76 | return *this; 77 | } 78 | Deque &operator=(Deque &&src) noexcept 79 | { 80 | if (this != &src) 81 | { 82 | Deque tmp(std::move(src)); 83 | swap(tmp); 84 | } 85 | return *this; 86 | } 87 | ~Deque() 88 | { 89 | if (!blocks) 90 | return; 91 | for (int i = firstBlock; i <= lastBlock; ++i) 92 | { 93 | destroy(blocks[i], i == firstBlock ? head : 0, i == lastBlock ? tail : BlockSize); 94 | dealloc(blocks[i]); 95 | } 96 | dealloc(blocks); 97 | } 98 | int size() const { return tail - head + BlockSize * (lastBlock - firstBlock); } 99 | bool empty() const { return tail == 0; } 100 | T &operator[](int pos) 101 | { 102 | return blocks[firstBlock + (head + pos) / BlockSize][(head + pos) % BlockSize]; 103 | } 104 | void push_back(const T &value) 105 | { 106 | if (lastBlock == blockCap - 1 && tail == BlockSize) 107 | expand(); 108 | if (tail == BlockSize) 109 | { 110 | blocks[++lastBlock] = alloc(BlockSize); 111 | blocks[lastBlock][0] = value; 112 | tail = 1; 113 | } 114 | else 115 | blocks[lastBlock][tail++] = value; 116 | } 117 | void pop_back() //assert(tail!=0) 118 | { 119 | if (tail == 1) 120 | { 121 | destroy(&blocks[lastBlock][0]); 122 | dealloc(blocks[lastBlock--]); 123 | tail = BlockSize; 124 | } 125 | else 126 | destroy(&blocks[lastBlock][--tail]); 127 | } 128 | void push_front(const T &value) 129 | { 130 | if (firstBlock == 0 && head == 0) 131 | expand(); 132 | if (head == 0) 133 | { 134 | blocks[--firstBlock] = alloc(BlockSize); 135 | blocks[firstBlock][head = BlockSize - 1] = value; 136 | } 137 | else 138 | blocks[firstBlock][--head] = value; 139 | } 140 | void pop_front() 141 | { 142 | if (head == BlockSize - 1) 143 | { 144 | destroy(&blocks[firstBlock][BlockSize - 1]); 145 | dealloc(blocks[firstBlock++]); 146 | head = 0; 147 | } 148 | else 149 | destroy(&blocks[firstBlock][head++]); 150 | } 151 | class iterator 152 | { 153 | public: 154 | typedef std::random_access_iterator_tag iterator_category; 155 | typedef T value_type; 156 | typedef int difference_type; 157 | typedef T *pointer; 158 | typedef T &reference; 159 | typedef const T &const_reference; 160 | typedef const T *const_pointer; 161 | private: 162 | Block *which; 163 | int where; 164 | public: 165 | iterator(Block *which, int where) :which(which), where(where) {} 166 | T &operator*() { return (*which)[where]; } 167 | T *operator->() { return (*which) + where; } 168 | iterator &operator+=(int shift) 169 | { 170 | which += (where + shift) / BlockSize; 171 | where = (where + shift) % BlockSize; 172 | return *this; 173 | } 174 | iterator operator+(int shift) const { iterator ret(*this); return ret += shift; } 175 | iterator &operator-=(int shift) 176 | { 177 | which += (where - shift) / BlockSize; 178 | where = (where - shift) % BlockSize; 179 | if (where < 0) where += BlockSize, --which; 180 | return *this; 181 | } 182 | iterator operator-(int shift) const { iterator ret(*this); return ret -= shift; } 183 | int operator-(iterator rhs) const { return where - rhs.where + BlockSize * (which - rhs.which); } 184 | iterator &operator++() 185 | { 186 | if (where == BlockSize - 1) 187 | ++which, where = 0; 188 | else 189 | ++where; 190 | return *this; 191 | } 192 | iterator &operator--() 193 | { 194 | if (where == 0) 195 | --which, where = BlockSize - 1; 196 | else 197 | --where; 198 | return *this; 199 | } 200 | iterator operator++(int) { iterator ret(*this); ++*this; return ret; } 201 | iterator operator--(int) { iterator ret(*this); --*this; return ret; } 202 | bool operator<(iterator rhs) const { return which != rhs.which ? which < rhs.which : where < rhs.where; } 203 | bool operator>(iterator rhs) const { return which != rhs.which ? which > rhs.which : where > rhs.where; } 204 | bool operator<=(iterator rhs) const { return *this - rhs <= 0; } 205 | bool operator>=(iterator rhs) const { return *this - rhs >= 0; } 206 | bool operator==(iterator rhs) const { return where == rhs.where && which == rhs.which; } 207 | bool operator!=(iterator rhs) const { return where != rhs.where || which != rhs.which; } 208 | }; 209 | iterator begin() { return iterator(blocks + firstBlock, head); } 210 | //直接传tail,tail可能为BlockSize,但是正常的迭代器不可能是BlockSize,从而永远不等 211 | iterator end() { return ++iterator(blocks + lastBlock, tail - 1); } 212 | }; 213 | } 214 | -------------------------------------------------------------------------------- /toy/template/SIUnit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace ds 6 | { 7 | //长度,质量,时间,电流,温度,物质的量,光强 8 | template 9 | struct Unit 10 | { 11 | double value; 12 | Unit operator-() const { return Unit(-value); } 13 | Unit &operator+=(Unit rhs) { return value += rhs.value, *this; } 14 | Unit &operator-=(Unit rhs) { return value -= rhs.value, *this; } 15 | friend Unit operator+(Unit lhs, Unit rhs) { return lhs += rhs; } 16 | friend Unit operator-(Unit lhs, Unit rhs) { return lhs -= rhs; } 17 | template 18 | friend auto operator*(Unit lhs, Unit rhs) 19 | { 20 | return Unit(lhs.value * rhs.value); 21 | } 22 | template 23 | friend auto operator/(Unit lhs, Unit rhs) 24 | { 25 | return Unit(lhs.value / rhs.value); 26 | } 27 | Unit &operator*=(double rhs) { return value *= rhs, *this; } 28 | Unit &operator/=(double rhs) { return value /= rhs, *this; } 29 | friend Unit operator*(Unit lhs, double rhs) { return lhs *= rhs; } 30 | friend Unit operator*(double lhs, Unit rhs) { return rhs *= lhs; } 31 | friend Unit operator/(Unit lhs, double rhs) { return Unit(lhs.value / rhs); } 32 | 33 | bool operator<(Unit rhs) const { return value < rhs.value; } 34 | bool operator>(Unit rhs) const { return value > rhs.value; } 35 | bool operator<=(Unit rhs) const { return value <= rhs.value; } 36 | bool operator>=(Unit rhs) const { return value >= rhs.value; } 37 | bool operator==(Unit rhs) const { return value == rhs.value; } 38 | bool operator!=(Unit rhs) const { return value != rhs.value; } 39 | 40 | //一个物理量的实数次方没有意义(纯数值除外),而且每一个量纲都必须整除 41 | //因为MSVC的日常bug,没办法写成SFINAE的语法,只能用static_assert 42 | template 43 | friend auto pow(Unit x) 44 | { 45 | static_assert(L * Num % Denom == 0 && M * Num % Denom == 0 && T * Num % Denom == 0 && I * Num % Denom == 0 && Θ * Num % Denom == 0 && N * Num % Denom == 0 && J * Num % Denom == 0, 46 | "fractional dimen is illgeal"); 47 | return Unit(std::pow(x.value, Num * 1.0 / Denom)); 48 | } 49 | 50 | //纯数值允许非explicit初始化,有单位数值必须explicit初始化 51 | template > 52 | constexpr Unit(double value = 0.0) :value(value) {} 53 | constexpr explicit Unit(double value = 0.0) :value(value) {} 54 | 55 | //同上 56 | template > 57 | operator double() const { return value; } 58 | explicit operator double() const { return value; } 59 | }; 60 | namespace unit 61 | { 62 | using Numeric = Unit<0, 0, 0, 0, 0, 0, 0>; 63 | using Length = Unit<1, 0, 0, 0, 0, 0, 0>; 64 | using Mass = Unit<0, 1, 0, 0, 0, 0, 0>; 65 | using Time = Unit<0, 0, 1, 0, 0, 0, 0>; 66 | using ElectricCurrent = Unit<0, 0, 0, 1, 0, 0, 0>; 67 | using Temperature = Unit<0, 0, 0, 0, 1, 0, 0>; 68 | using Amount = Unit<0, 0, 0, 0, 0, 1, 0>; 69 | using LuminousIntensity = Unit<0, 0, 0, 0, 0, 0, 1>; 70 | 71 | constexpr Length operator""_m(long double value) { return Length(static_cast(value)); } 72 | constexpr Length operator""_m(unsigned long long value) { return Length(static_cast(value)); } 73 | constexpr Mass operator""_kg(long double value) { return Mass(static_cast(value)); } 74 | constexpr Mass operator""_kg(unsigned long long value) { return Mass(static_cast(value)); } 75 | constexpr Time operator""_s(long double value) { return Time(static_cast(value)); } 76 | constexpr Time operator""_s(unsigned long long value) { return Time(static_cast(value)); } 77 | constexpr ElectricCurrent operator""_A(long double value) { return ElectricCurrent(static_cast(value)); } 78 | constexpr ElectricCurrent operator""_A(unsigned long long value) { return ElectricCurrent(static_cast(value)); } 79 | constexpr Temperature operator""_K(long double value) { return Temperature(static_cast(value)); } 80 | constexpr Temperature operator""_K(unsigned long long value) { return Temperature(static_cast(value)); } 81 | constexpr Amount operator""_mol(long double value) { return Amount(static_cast(value)); } 82 | constexpr Amount operator""_mol(unsigned long long value) { return Amount(static_cast(value)); } 83 | constexpr LuminousIntensity operator""_cd(long double value) { return LuminousIntensity(static_cast(value)); } 84 | constexpr LuminousIntensity operator""_cd(unsigned long long value) { return LuminousIntensity(static_cast(value)); } 85 | 86 | using Velocity = decltype(Length() / Time()); 87 | using Acceleration = decltype(Velocity() / Time()); 88 | using Force = decltype(Mass() * Acceleration()); 89 | using Work = decltype(Force() * Length()); 90 | using Power = decltype(Work() / Time()); 91 | using Area = decltype(Length() * Length()); 92 | using Volume = decltype(Length() * Length() * Length()); 93 | using Pressure = decltype(Force() / Area()); 94 | 95 | using Momentum = decltype(Mass() * Velocity()); 96 | using AngularMomentum = decltype(Length() * Momentum()); 97 | using Moment = decltype(Length() * Force()); //力矩 98 | 99 | constexpr Velocity operator""_m_s(long double value) { return Velocity(static_cast(value)); } 100 | constexpr Velocity operator""_m_s(unsigned long long value) { return Velocity(static_cast(value)); } 101 | constexpr Acceleration operator""_m_s2(long double value) { return Acceleration(static_cast(value)); } 102 | constexpr Acceleration operator""_m_s2(unsigned long long value) { return Acceleration(static_cast(value)); } 103 | constexpr Force operator""_N(long double value) { return Force(static_cast(value)); } 104 | constexpr Force operator""_N(unsigned long long value) { return Force(static_cast(value)); } 105 | constexpr Work operator""_J(long double value) { return Work(static_cast(value)); } 106 | constexpr Work operator""_J(unsigned long long value) { return Work(static_cast(value)); } 107 | constexpr Power operator""_W(long double value) { return Power(static_cast(value)); } 108 | constexpr Power operator""_W(unsigned long long value) { return Power(static_cast(value)); } 109 | constexpr Area operator""_m2(long double value) { return Area(static_cast(value)); } 110 | constexpr Area operator""_m2(unsigned long long value) { return Area(static_cast(value)); } 111 | constexpr Volume operator""_m3(long double value) { return Volume(static_cast(value)); } 112 | constexpr Volume operator""_m3(unsigned long long value) { return Volume(static_cast(value)); } 113 | constexpr Pressure operator""_pa(long double value) { return Pressure(static_cast(value)); } 114 | constexpr Pressure operator""_pa(unsigned long long value) { return Pressure(static_cast(value)); } 115 | } 116 | } -------------------------------------------------------------------------------- /associative/AVL.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "TreeUtil.h" 6 | #include "Util.h" 7 | namespace ds 8 | { 9 | template 10 | class AVL 11 | { 12 | private: 13 | typedef typename Traits::KeyType KeyType; 14 | typedef typename Traits::ValueType ValueType; 15 | typedef typename Traits::KeyCompare KeyCompare; 16 | KeyCompare comp; 17 | public: 18 | struct Node; 19 | typedef Node* LinkType; 20 | typedef std::pair NodePair; 21 | struct Node 22 | { 23 | LinkType p = nullptr, ch[2] = { nullptr }; 24 | ValueType value; 25 | int sz = 0, h = 0; 26 | const KeyType &key() const { return Traits::KeyOf(value); } 27 | ValueType &operator*() { return value; } 28 | ValueType *operator->() { return &(operator*()); } 29 | LinkType clone(LinkType p,LinkType l,LinkType r) const 30 | { 31 | LinkType ret = new Node(p, l, r, ValueType(value)); 32 | ret->sz = sz, ret->h = h; 33 | return ret; 34 | } 35 | Node() = default; 36 | Node(LinkType p, LinkType l, LinkType r, const ValueType &value) :p(p), value(value), sz(1), h(1) 37 | { 38 | ch[0] = l, ch[1] = r; //默认初始化时size和h置为0 39 | } 40 | }; 41 | private: 42 | LinkType nil_, root_; 43 | static void updH(LinkType x) { x->h = max(x->ch[0]->h, x->ch[1]->h) + 1; } 44 | static void updSz(LinkType x) { x->sz = x->ch[0]->sz + x->ch[1]->sz + 1; } 45 | void rotate(LinkType x) //把x向上旋转 46 | { 47 | LinkType p = x->p, g = p->p; 48 | const bool rx = x == p->ch[1], rp = p == g->ch[1]; 49 | 50 | x->p = g; //把x接到g上 51 | g->ch[rp] = x; 52 | 53 | p->ch[rx] = x->ch[!rx]; //把p的与x异侧的孙节点接到p上 54 | x->ch[!rx]->p = p; 55 | 56 | p->p = x; //把p接到x上 57 | x->ch[!rx] = p; 58 | 59 | if (root_ == p) 60 | root_ = x; 61 | updSz(p), updH(p), updSz(x), updH(x); 62 | } 63 | void transplant(LinkType dest, LinkType sour)//并不处理dest的子节点 64 | { 65 | LinkType dp = dest->p; 66 | sour->p = dp; 67 | if (dp == nil_) 68 | root_ = sour; 69 | else 70 | dp->ch[dest == dp->ch[1]] = sour; 71 | } 72 | static bool isBalance(LinkType x) 73 | { 74 | const int delta = x->ch[1]->h - x->ch[0]->h; 75 | return delta <= 1 && delta >= -1; 76 | } 77 | static bool checkAndUpd(LinkType x) 78 | { 79 | const int h = max(x->ch[0]->h, x->ch[1]->h) + 1; 80 | if (x->h == h) 81 | return true; 82 | x->h = h; 83 | return false; 84 | } 85 | static bool check(LinkType x) { return x->h == max(x->ch[0]->h, x->ch[1]->h) + 1; } 86 | public: 87 | LinkType nextNode(Node *x)const { return TreeUtil::nextNode(x, nil_); } 88 | LinkType prevNode(Node *x)const { return TreeUtil::prevNode(x, nil_, root_); } 89 | LinkType kth(const int k)const { return TreeUtil::kth(root_, nil_, k); } 90 | int lower(const KeyType &key, const bool afterEqual) const { return TreeUtil::lower(key, root_, nil_, afterEqual, comp); } 91 | NodePair findNode(const KeyType &key, LinkType x = nullptr) //从x开始搜 92 | { 93 | if (!x) x = root_; 94 | LinkType p = nil_; 95 | while (x != nil_) 96 | { 97 | if (comp(x->key(), key)) 98 | p = x, x = x->ch[1]; 99 | else if (!comp(key, x->key())) 100 | return { x,p }; 101 | else 102 | p = x, x = x->ch[0]; 103 | } 104 | return { nullptr,p }; 105 | } 106 | LinkType insert(LinkType x, const ValueType &value) 107 | { 108 | LinkType z = new Node(x, nil_, nil_, value); 109 | if (x == nil_) x = root_ = z; 110 | else x->ch[comp(x->key(), Traits::KeyOf(value))] = z; 111 | LinkType tmpx = x; 112 | while (tmpx != nil_) 113 | ++tmpx->sz, tmpx = tmpx->p; 114 | while (x != root_) 115 | { 116 | if (checkAndUpd(x)) 117 | break; 118 | if (!isBalance(x->p)) 119 | { 120 | const bool rz = z == x->ch[1], rx = x == x->p->ch[1]; 121 | if (rz^rx) 122 | rotate(z), rotate(z); 123 | else 124 | rotate(x); 125 | break;//插入至多修复一次,但是不知道在那里修复 126 | } 127 | z = x, x = x->p; 128 | } 129 | return z; 130 | } 131 | LinkType insert(const ValueType &value) 132 | { 133 | NodePair np = findNode(Traits::KeyOf(value)); 134 | if (np.first) 135 | return np.first; 136 | return insert(np.second, value); 137 | } 138 | void erase(LinkType z) 139 | { 140 | LinkType tmpz = z; 141 | while (tmpz != nil_) 142 | --tmpz->sz, tmpz = tmpz->p; 143 | LinkType y = z, x; 144 | if (z->ch[0] == nil_) 145 | x = z->ch[1], transplant(z, x); 146 | else if (z->ch[1] == nil_) 147 | x = z->ch[0], transplant(z, x); 148 | else 149 | { 150 | const int argmax = z->ch[0]->h > z->ch[1]->h ? 0 : 1; 151 | y = TreeUtil::extremeChild(z->ch[argmax], nil_, !argmax); //前驱 or 后继 152 | x = y->ch[argmax]; 153 | if (y->p == z) 154 | x->p = y; //这一步不是多余的!!!如果x是nil_,x->p显然不一定是y 155 | else 156 | { 157 | LinkType tmpy = y; 158 | while (tmpy != z) 159 | { 160 | --tmpy->sz; 161 | tmpy = tmpy->p; 162 | } 163 | transplant(y, y->ch[argmax]); 164 | y->ch[argmax] = z->ch[argmax]; 165 | y->ch[argmax]->p = y; 166 | } 167 | transplant(z, y); 168 | y->ch[!argmax] = z->ch[!argmax], y->ch[!argmax]->p = y; 169 | updH(y), updSz(y); 170 | } 171 | delete z; 172 | //现在,x->p是唯一可能破坏高度平衡的节点 173 | while (x != root_) 174 | { 175 | if (x != nil_) 176 | updH(x); 177 | 178 | if (!isBalance(x->p)) 179 | { 180 | bool xSide = x == x->p->ch[1], sameSide = true; 181 | x = x->p->ch[xSide ^= 1];//x的另一边 182 | //这是经过缜密分析得到的结果 183 | //记x的h=H,可以证明,当且仅当与x同侧的孩子的h=H-2,异侧的孩子的h=H-1时,不能选同侧的孩子 184 | //而且可以选异侧的孩子 185 | if (x->ch[xSide]->h == x->h - 2 && x->ch[!xSide]->h == x->h - 1) 186 | z = x->ch[!xSide], sameSide = false; 187 | else 188 | z = x->ch[xSide]; 189 | if (!sameSide) 190 | rotate(z), rotate(z), x = z; //此时z==x->p 191 | else 192 | rotate(x);//此时不用更新 193 | } 194 | else 195 | x = x->p; 196 | } 197 | } 198 | LinkType minChild() const { return TreeUtil::extremeChild(root_, nil_, 0); } 199 | LinkType maxChild() const { return TreeUtil::extremeChild(root_, nil_, 1);} 200 | int size() const { return root_->sz; } 201 | LinkType nil() const { return nil_; } 202 | void clear() { TreeUtil::clear(root_, nil_); } 203 | void swap(AVL &rhs) noexcept 204 | { 205 | std::swap(root_, rhs.root_); 206 | std::swap(nil_, rhs.nil_); 207 | } 208 | AVL(KeyCompare comp = KeyCompare()) :comp(comp), nil_(new Node) 209 | { 210 | root_ = nil_; 211 | root_->p = root_->ch[0] = root_->ch[1] = nil_; 212 | } 213 | AVL(const AVL&rhs) 214 | { 215 | nil_ = new Node; 216 | if (rhs.root_ == rhs.nil_) 217 | { 218 | root_ = nil_; 219 | root_->p = root_->ch[0] = root_->ch[1] = nil_; 220 | } 221 | else 222 | { 223 | root_ = rhs.root_->clone(nil_, nil_, nil_); 224 | TreeUtil::cpy(root_, nil_, rhs.root_, rhs.nil_); 225 | } 226 | } 227 | AVL& operator=(const AVL &rhs) 228 | { 229 | if (this != &rhs) 230 | { 231 | AVL tmp(rhs); 232 | swap(tmp); 233 | } 234 | return *this; 235 | } 236 | AVL(AVL &&rhs) noexcept 237 | { 238 | if (this != &rhs) 239 | { 240 | nil_ = rhs.nil_; 241 | root_ = rhs.root_; 242 | rhs.nil_ = rhs.root_ = nullptr; 243 | } 244 | } 245 | AVL& operator=(AVL &&rhs) noexcept 246 | { 247 | if (this != &rhs) 248 | { 249 | ~AVL(); 250 | nil_ = rhs.nil_; 251 | root_ = rhs.root_; 252 | rhs.nil_ = rhs.root_ = nullptr; 253 | } 254 | return *this; 255 | } 256 | ~AVL() 257 | { 258 | clear(); 259 | delete nil_; 260 | } 261 | }; 262 | } 263 | -------------------------------------------------------------------------------- /associative/HashMap-OpenAddress.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "HashMapUtil.h" 3 | #include 4 | #include 5 | #include "Algorithm.h" 6 | 7 | namespace ds 8 | { 9 | //不与stl的unordered_map兼容,纯粹自己发挥 10 | template 11 | class HashMap 12 | { 13 | typedef typename OpenAddressT::CodeType CodeType; 14 | typedef std::pair ValueType; 15 | typedef std::pair InputType; 16 | struct Node 17 | { 18 | enum State { empty, used, deleted }; 19 | ValueType value; 20 | int state; 21 | bool terminal() const { return state == empty; } //一个empty的Node意味着序列的终止,deleted的则只是一个洞 22 | ValueType *operator->() { return &value; } 23 | Node(const ValueType &value) :value(value), state(used) {} 24 | //记一个移动构造的坑,原来是这样写的: 25 | //Node(ValueType &&value) noexcept :value(std::move(value)), state(used) {} 26 | //每次调用Node的移动构造的时候,虽然写了value(std::move(value)),但是我选的K(比如string)并没有移动 27 | //这是因为ValueType是pair,所以得到了一个const K &&,它无法匹配K &&,而是会匹配const K &,所以发生了复制 28 | //const_cast似乎是UB,不用了;rehash的时候,我memcpy谁还能拦得住吗? 29 | Node(InputType &&value) noexcept : value(std::move(value.first),std::move(value.second)), state(used) {} 30 | }; 31 | Node *nextNode(Node *x) const 32 | { 33 | Node *last = table + capacity; 34 | if (x++ == last) //end()再++仍是end() 35 | return last; 36 | while (x != last && x->state != Node::used) 37 | ++x; 38 | return x; 39 | } 40 | Node *prevNode(Node *x) const 41 | { 42 | Node *tmp = x, *first = table - 1; 43 | --x; //正常情况下x不可能越过first,但是可以越过last,所以这样特判 44 | while (x != first && x->state != Node::used) 45 | --x; 46 | if (x->state != Node::used) //begin()再--仍是begin() 47 | return tmp; 48 | return x; 49 | } 50 | public: 51 | class iterator 52 | { 53 | HashMap *container; 54 | Node *self; 55 | public: 56 | typedef std::bidirectional_iterator_tag iterator_category; 57 | typedef std::pair value_type; 58 | typedef value_type *pointer; 59 | typedef const value_type *const_pointer; 60 | typedef value_type &reference; 61 | typedef const value_type &const_reference; 62 | pointer operator->() { return &self->value; } 63 | reference operator*() { return self->value; } 64 | iterator& operator++() { self = container->nextNode(self); return *this; } 65 | iterator operator++(int) { iterator tmp = *this; operator++(); return tmp; } 66 | iterator& operator--() { self = container->prevNode(self); return *this; } 67 | iterator operator--(int) { iterator tmp = *this; operator--(); return tmp; } 68 | bool operator==(const iterator &rhs) const { return self == rhs.self; } 69 | bool operator!=(const iterator &rhs) const { return self != rhs.self; } 70 | iterator(Node *self, HashMap *container) :self(self), container(container) {} 71 | }; 72 | private: 73 | Node *table; 74 | int size_ = 0, capacity = 0; 75 | float maxFactor = 0.75f; 76 | CodeType hashCode(CodeType raw) const 77 | { 78 | //为了保证探查序列取遍[0,capacity),这里不能做移位+异或之类的干扰操作(这个操作可以在哈希函数里做) 79 | //而且对散列函数的取值也有要求 80 | return raw & (capacity - 1); 81 | } 82 | void rehash() 83 | { 84 | if (capacity * maxFactor < size_) 85 | { 86 | Node *otbl = table; 87 | int ocap = capacity; 88 | table = reinterpret_cast(malloc((capacity <<= 1) * sizeof(Node))); 89 | memset(table, 0, capacity * sizeof(Node)); 90 | for (int i = 0; i < ocap; ++i) 91 | if (otbl[i].state == Node::used) 92 | { 93 | OpenAddressT hasher(otbl[i]->first); 94 | auto h = hashCode(hasher.probe(0)); 95 | for (int j = 0; !table[h].terminal() && j < capacity; h = hashCode(hasher.probe(++j))) 96 | ; //这里没有必要再检查deleted和相等,都不可能发生 97 | memcpy(table + h, otbl + i, sizeof(Node)); 98 | } 99 | free(otbl); 100 | } 101 | } 102 | template 103 | std::pair insertUnchecked(P &&kv) 104 | { 105 | OpenAddressT hasher(kv.first); 106 | auto h = hashCode(hasher.probe(0)); 107 | int free = -1; 108 | for (int i = 0; !table[h].terminal() && i < capacity; h = hashCode(hasher.probe(++i))) 109 | { 110 | if (table[h].state == Node::deleted && free == -1) 111 | free = h; 112 | else if (table[h]->first == kv.first) 113 | return { &table[h].value,false }; 114 | } 115 | free = (free != -1) ? free : h; 116 | new(table + free) Node(std::forward

(kv)); 117 | return { &table[free].value,true }; 118 | } 119 | public: 120 | void insert(const InputType &value) 121 | { 122 | if (insertUnchecked(value).second) 123 | ++size_; 124 | rehash(); 125 | } 126 | void insert(InputType &&value) 127 | { 128 | if (insertUnchecked(std::move(value)).second) 129 | ++size_; 130 | rehash(); 131 | } 132 | template ::value>::type> 133 | void insert(Args &&...args) 134 | { 135 | insert(InputType(std::forward(args)...)); 136 | } 137 | V &operator[](const K &key) 138 | { 139 | auto pr = insertUnchecked(std::make_pair(key,V())); 140 | if (pr.second) 141 | ++size_; 142 | return pr.first->second; 143 | } 144 | ValueType *find(const K&key) const 145 | { 146 | OpenAddressT hasher(key); 147 | auto h = hashCode(hasher.probe(0)); 148 | for (int i = 0; !table[h].terminal() && i < capacity; h = hashCode(hasher.probe(++i))) 149 | if (table[h].state != Node::deleted && table[h]->first == key) 150 | return &(table[h].value); 151 | return nullptr; 152 | } 153 | void erase(const K &key) 154 | { 155 | OpenAddressT hasher(key); 156 | auto h = hashCode(hasher.probe(0)); 157 | for (int i = 0; !table[h].terminal() && i < capacity; h = hashCode(hasher.probe(++i))) 158 | if (table[h].state != Node::deleted && table[h]->first == key) 159 | { 160 | --size_; 161 | table[h].~Node(); 162 | table[h].state = Node::deleted; 163 | return; 164 | } 165 | } 166 | int size() const { return size_; } 167 | iterator begin() { return iterator(nextNode(table - 1) ,this); } 168 | iterator end() { return iterator(table + capacity, this); } 169 | void swap(HashMap &rhs) noexcept 170 | { 171 | ds::bitwiseSwap(this, &rhs); 172 | } 173 | HashMap(int capacity = 16) : capacity(capacity) 174 | { 175 | table = reinterpret_cast(malloc(capacity * sizeof(Node))); 176 | memset(table, 0, capacity * sizeof(Node)); 177 | } 178 | HashMap(const HashMap &rhs):size_(rhs.size_),capacity(rhs.capacity), maxFactor(rhs.maxFactor) 179 | { 180 | table = reinterpret_cast(malloc(capacity * sizeof(Node))); 181 | memset(table, 0, capacity * sizeof(Node)); 182 | for (int i = 0; i < capacity; ++i) 183 | if (rhs.table[i].state == Node::used) 184 | insertUnchecked(rhs.table[i].value); 185 | } 186 | HashMap(HashMap &&rhs) noexcept 187 | { 188 | if (this!=&rhs) 189 | { 190 | memcpy(this, &rhs, sizeof(HashMap)); 191 | memset(&rhs, 0, sizeof(HashMap)); 192 | } 193 | } 194 | HashMap& operator=(const HashMap &rhs) 195 | { 196 | if (this != &rhs) 197 | { 198 | HashMap tmp(rhs); 199 | swap(tmp); 200 | } 201 | return *this; 202 | } 203 | HashMap& operator=(HashMap &&rhs) noexcept 204 | { 205 | if (this != &rhs) 206 | { 207 | HashMap tmp(std::move(rhs)); 208 | swap(tmp); 209 | } 210 | return *this; 211 | } 212 | ~HashMap() 213 | { 214 | if (!std::is_trivially_destructible::value) 215 | for (int i = 0; i < capacity; ++i) 216 | if (table[i].state == Node::used) 217 | table[i].~Node(); 218 | free(table); 219 | } 220 | }; 221 | } 222 | --------------------------------------------------------------------------------