├── LICENSE ├── Makefile ├── README ├── algorithms.h ├── includes.txt ├── library.txt ├── library_tests.cc ├── macros.h ├── math.h ├── mathtypes.h ├── matrix.h ├── misc.h ├── old ├── avl.cc ├── bfspqtemp.cc ├── bfstemp.cc ├── bigint.cc ├── bigint2.cc ├── conway.cc ├── die.cc ├── fract.cc ├── geom2d.cc ├── library.cc ├── math.cc ├── misc.cc ├── rangeop.cc ├── rangeop2.cc ├── rangeop3.cc ├── rangeoptest.cc ├── sgraph.cc ├── tokenize.cc └── unionfind.cc ├── parsing.h └── process.cc /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Derek Kisman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for process.exe and testing library code. 2 | 3 | CC = g++ 4 | WARNS = -Wall -Wno-sign-compare 5 | CFLAGS = -O3 -std=c++11 ${WARNS} 6 | 7 | PROCESS_ARGS = includes.txt library.txt 8 | LIBRARY = algorithms.h macros.h math.h mathtypes.h matrix.h misc.h parsing.h 9 | 10 | 11 | all: process.exe library_tests.exe 12 | 13 | test: library_tests.exe 14 | ./library_tests.exe 15 | 16 | process.exe: process.cc 17 | $(CC) -o $@ $< $(CFLAGS) 18 | 19 | processed_tests.cc: library_tests.cc process.exe $(PROCESS_ARGS) $(LIBRARY) 20 | ./process.exe $(PROCESS_ARGS) <$< >$@ 21 | 22 | library_tests.exe: processed_tests.cc 23 | $(CC) -o $@ $< $(CFLAGS) 24 | 25 | clean: 26 | rm -f "process.exe" "library_tests.exe" "processed_tests.cc" 27 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | "process" is the program I use to automatically add includes and library code 2 | to my C++ submissions before submitting. You'll probably have to change a 3 | few things before you can use it: 4 | - Rename the .exes in the Makefile (if you're on Linux rather than Cygwin). 5 | - Rename the directories in library.txt to your repository location. 6 | - If you want to use it from gvim (say by pushing CTRL-P), add the following to 7 | your .gvimrc: 8 | nmap :%!{repository directory}/process.exe {repository directory}/includes.txt {repository directory}/library.txt 9 | -------------------------------------------------------------------------------- /algorithms.h: -------------------------------------------------------------------------------- 1 | #ifndef __ALGORITHMS_H 2 | #define __ALGORITHMS_H 3 | 4 | //// Common programming contest algorithms. 5 | //// Formatted for process.exe. 6 | 7 | //// *** Graph theory *** 8 | 9 | // Returns -1 for unmatched items. 10 | // Complexity: O(V*E) 11 | VI BipartiteMatch(const VVI &mat, VI *back_match = NULL) { 12 | int max_item = -1; 13 | VI fmat(mat.size(), -1), seen(mat.size(), -1), prev(mat.size()); 14 | for (int i = 0; i < mat.size(); i++) if (mat[i].size()) 15 | max_item >?= *max_element(mat[i].begin(), mat[i].end()); 16 | VI bmat(max_item+1, -1); 17 | 18 | for (int i = 0; i < mat.size(); i++) { 19 | VI q(1, i); 20 | seen[i] = i; prev[i] = -1; 21 | int x, y; 22 | while (!q.empty()) { 23 | x = q.back(); q.pop_back(); 24 | for (VI::const_iterator it = mat[x].begin(); it != mat[x].end(); ++it) { 25 | int bm = bmat[*it]; 26 | if (bm == -1) {y = *it; goto found_match;} 27 | if (seen[bm] < i) { 28 | seen[bm] = i; prev[bm] = x; 29 | q.push_back(bm); 30 | } 31 | } 32 | } 33 | continue; 34 | found_match: 35 | while (x != -1) { 36 | bmat[y] = x; 37 | swap(y, fmat[x]); 38 | x = prev[x]; 39 | } 40 | } 41 | 42 | if (back_match) *back_match = bmat; 43 | return fmat; 44 | } 45 | 46 | #endif // __ALGORITHMS_H 47 | -------------------------------------------------------------------------------- /includes.txt: -------------------------------------------------------------------------------- 1 | #include vector< 2 | #include queue< priority_queue< 3 | #include set< multiset< 4 | #include map< multimap< 5 | #include bitset< 6 | #include list< 7 | #include deque< 8 | #include stack< 9 | #include complex< 10 | #include hash_map< 11 | #include hash_set< 12 | #include string 13 | #include sort( stable_sort( make_heap( push_heap( pop_heap( 14 | lower_bound( upper_bound( equal_range( binary_search( 15 | find( find_first_of( count( min( max( swap( fill( copy( 16 | next_permutation( prev_permutation( 17 | remove( replace( reverse( rotate( random_shuffle( 18 | min_element( max_element( nth_element( mismatch( 19 | set_difference( set_intersection( set_union( 20 | set_symmetric_difference( merge( unique( adjacent_find( 21 | lexicographical_compare( lexicographical_compare_3way( 22 | equal( includes( 23 | #include accumulate( partial_sum( adjacent_difference( 24 | inner_product( 25 | #include cin cout cerr istream ostream 26 | #include ifstream ofstream ifstream( ofstream( 27 | #include istringstream ostringstream 28 | #include assert( 29 | #include sin( cos( tan( asin( acos( atan( atan2( sinh( cosh( tanh( 30 | sqrt( hypot( abs( exp( pow( ceil( floor( fmod( log( log10( 31 | fabs( M_PI 32 | #include printf( scanf( fprintf( fscanf( sprintf( sscanf( 33 | getc( fgetc( putc( fputc( getchar( putchar( ungetc( 34 | FILE stdin stdout stderr feof( fclose( fflush( 35 | #include rand( srand( 36 | #include memcpy( memmove( memchr( memset( 37 | strcpy( strncpy( strcat( strncat( strcmp( strncmp( 38 | strchr( strrchr( strstr( strtok( strlen( 39 | #include time( clock( CLOCKS_PER_SEC 40 | -------------------------------------------------------------------------------- /library.txt: -------------------------------------------------------------------------------- 1 | c:/cygwin/home/SnapDragon/acm/ContestLibrary/algorithms.h 2 | c:/cygwin/home/SnapDragon/acm/ContestLibrary/macros.h 3 | c:/cygwin/home/SnapDragon/acm/ContestLibrary/math.h 4 | c:/cygwin/home/SnapDragon/acm/ContestLibrary/mathtypes.h 5 | c:/cygwin/home/SnapDragon/acm/ContestLibrary/matrix.h 6 | c:/cygwin/home/SnapDragon/acm/ContestLibrary/misc.h 7 | c:/cygwin/home/SnapDragon/acm/ContestLibrary/parsing.h 8 | -------------------------------------------------------------------------------- /library_tests.cc: -------------------------------------------------------------------------------- 1 | void fail_test(const string& test, const string& err) { 2 | cerr << test << " FAILED: " << err << endl; 3 | exit(1); 4 | } 5 | 6 | void TEST_PokerHand() { 7 | cerr << " Running TEST_PokerHand()..." << endl; 8 | string hands[] = { 9 | "2C 3D 4H 5S 7H 0", 10 | "2S 3D 4H 5C 7S (equal)", 11 | "2S 3C 4S 6S 7S", 12 | "3C 4S 5D 7D 8S", 13 | "3S 4C 5S 8S 9H", 14 | "3S 4C 5S 8S TH", 15 | "2S 3C 4S 8S JH", 16 | "3S 4C 5S 8S JH", 17 | "2S 3C 5S 8S QH", 18 | "3C 4C 5D 8D QD", 19 | "3S 4C 5S 8S QH (equal)", 20 | "4D 6H 8C TS QC", 21 | "3D 7H 8C TS QC", 22 | "4D 5H 9C TS QC", 23 | "4D 6H 7C JS QC", 24 | "3S 4C 5S 6S KH", 25 | "3S 4C 5S 8S KH", 26 | "4D 6H 7C 9S KC", 27 | "3S 4C 5D TS KD", 28 | "3D 4C 5S JS KC", 29 | "6D 7C 8S QS KC", 30 | "2S 3C 4D 6D AH", 31 | "2S 3C 4S KS AS", 32 | "2H 3C QS KS AH", 33 | "9H JC QD KD AS", 34 | "2D 2C 3D 4D 5S 1", 35 | "2S 2C 4D 6D 8H", 36 | "2H 2C 3D 7D 8H", 37 | "2D 2C 4D 5D 9S", 38 | "3S 3C 2D 4D 5S", 39 | "3H 3C JH QC KH", 40 | "3D 3C QC KD AH", 41 | "4S 4C 2D 3D 5S", 42 | "KS KC 3D 8H QS", 43 | "AS AC 3C 7C QS", 44 | "AS AC JD QD KH", 45 | "2S 2C 3H 3D 4S 2", 46 | "2S 2H 3H 3D 6S", 47 | "2H 2C 4H 4D 5S", 48 | "5S 5H 7D 7C JS", 49 | "4S 4H 8D 8C TS", 50 | "KS KC AS AC QS", 51 | "2S 2H 2D 3C 4S 3", 52 | "2S 2H 2C 7C 8S", 53 | "2S 2H 2D 7D 8C (equal)", 54 | "2S 2H 2D 6C 9S", 55 | "2D 2H 2C 7C 9S", 56 | "3D 3H 3C 2C 5S", 57 | "TD TS TC 3C 4S", 58 | "AD AC AS QC KS", 59 | "AD 2D 3D 4D 5C 4", 60 | "AH 2H 3C 4S 5S (equal)", 61 | "AS 2H 3C 4S 5D (equal)", 62 | "2H 3C 4S 5C 6C", 63 | "2H 3C 4S 5D 6D (equal)", 64 | "3S 4C 5H 6C 7S", 65 | "9H TH JH QD KS", 66 | "TS JC QS KC AD", 67 | "2C 3C 4C 5C 7C 5", 68 | "2D 3D 4D 5D 7D (equal)", 69 | "2H 3H 4H 5H 7H (equal)", 70 | "2S 3S 4S 5S 7S (equal)", 71 | "2C 3C 4C 5C 8C", 72 | "3C 5C 7C 9C JC", 73 | "2C 6C 7C 9C JC", 74 | "3S 4S 8S 9S JS", 75 | "3D 5D 6D TD JD", 76 | "3C 5C 7C 8C QC", 77 | "9H TH QH KH AH", 78 | "9H JH QH KH AH", 79 | "2S 2D 2C 3H 3S 6", 80 | "2S 2H 2C 4C 4D", 81 | "2S 2H 2D AD AS", 82 | "3S 3H 3D 2D 2S", 83 | "3C 3H 3D 4D 4C", 84 | "7S 7H 7D 3H 3S", 85 | "7S 7H 7C 5D 5C", 86 | "8S 8D 8C 4D 4C", 87 | "QS QH QC JH JC", 88 | "KH KD KS 2D 2S", 89 | "KS KH KD AH AD", 90 | "AS AC AD KH KC", 91 | "2C 2D 2H 2S 3C 7", 92 | "2C 2D 2H 2S 3D (equal)", 93 | "2C 2D 2H 2S 4D", 94 | "2C 2D 2H 2S 7H", 95 | "2C 2D 2H 2S AC", 96 | "3C 3D 3H 3S 2S", 97 | "3C 3D 3H 3S AD", 98 | "7C 7D 7H 7S 5C", 99 | "KC KD KH KS AD", 100 | "AC AD AH AS KS", 101 | "AC 2C 3C 4C 5C 8", 102 | "AD 2D 3D 4D 5D (equal)", 103 | "AH 2H 3H 4H 5H (equal)", 104 | "AS 2S 3S 4S 5S (equal)", 105 | "2C 3C 4C 5C 6C", 106 | "4C 5C 6C 7C 8C", 107 | "8D 9D TD JD QD", 108 | "9D TD JD QD KD", 109 | "TC JC QC KC AC 9", 110 | "TD JD QD KD AD (equal)", 111 | "TH JH QH KH AH (equal)", 112 | "TS JS QS KS AS (equal)", 113 | }; 114 | int nhands = sizeof(hands)/sizeof(string); 115 | vector > v; 116 | for (int i = 0; i < nhands; i++) { 117 | vector hand; 118 | for (int j = 0; j < 5; j++) { 119 | hand.push_back(CardToInt(hands[i][j*3], hands[i][j*3+1])); 120 | assert(hand.back() != -1); 121 | } 122 | random_shuffle(hand.begin(), hand.end()); 123 | v.push_back(make_pair(PokerHand(hand), hands[i])); 124 | //printf("%x %s\n", v.back().first, hands[i].c_str()); 125 | } 126 | 127 | sort(v.begin(), v.end()); 128 | int value = 0; 129 | for (int i = 0; i < nhands; i++) { 130 | if (v[i].second != hands[i]) { 131 | fail_test("PokerHands", "Saw \"" + v[i].second + 132 | "\", expected \"" + hands[i] + "\"."); 133 | } 134 | if (hands[i].size() == 16) { 135 | value = hands[i][15]-'0'; 136 | } 137 | if ((v[i].first>>24) != value) { 138 | fail_test("PokerHands", "Incorrect hand at \"" + hands[i] + "\"."); 139 | } 140 | if ((i && v[i].first == v[i-1].first) ^ (hands[i].size() == 22)) { 141 | fail_test("PokerHands", "Equality mismatch at \"" + hands[i] + "\"."); 142 | } 143 | } 144 | } 145 | 146 | bool CallIsPrime(int func, uint64 n) { 147 | if (func == 0) return IsPrime(n); 148 | if (func == 1) return IsPrimeFast(n); 149 | if (func == 2) return IsPrimeFast48(n); 150 | if (func == 3) return IsPrimeFast64(n); 151 | return false; 152 | } 153 | void TEST_IsPrimeFast() { 154 | cerr << " Running TEST_IsPrimeFast()..." << endl; 155 | static const uint64 A014233[] = // From OEIS. 156 | {2047LL, 1373653LL, 25326001LL, 3215031751LL, 2152302898747LL, 157 | 3474749660383LL, 341550071728321LL, 341550071728321LL, 158 | 3825123056546413051LL, 3825123056546413051LL, 3825123056546413051LL}; 159 | uint64 limits[4] = {(1LL<<34)-1, (1LL<<32)-1, (1LL<<42)-1, ~0ULL}; 160 | int p2prime[65][10] = {{},{},{},{},{},{},{},{}, 161 | {5, 15, 17, 23, 27, 29, 33, 45, 57, 59}, /* 8 */ 162 | {3, 9, 13, 21, 25, 33, 45, 49, 51, 55}, /* 9 */ 163 | {3, 5, 11, 15, 27, 33, 41, 47, 53, 57}, /* 10 */ 164 | {9, 19, 21, 31, 37, 45, 49, 51, 55, 61}, /* 11 */ 165 | {3, 5, 17, 23, 39, 45, 47, 69, 75, 77}, /* 12 */ 166 | {1, 13, 21, 25, 31, 45, 69, 75, 81, 91}, /* 13 */ 167 | {3, 15, 21, 23, 35, 45, 51, 65, 83, 111}, /* 14 */ 168 | {19, 49, 51, 55, 61, 75, 81, 115, 121, 135}, /* 15 */ 169 | {15, 17, 39, 57, 87, 89, 99, 113, 117, 123}, /* 16 */ 170 | {1, 9, 13, 31, 49, 61, 63, 85, 91, 99}, /* 17 */ 171 | {5, 11, 17, 23, 33, 35, 41, 65, 75, 93}, /* 18 */ 172 | {1, 19, 27, 31, 45, 57, 67, 69, 85, 87}, /* 19 */ 173 | {3, 5, 17, 27, 59, 69, 129, 143, 153, 185}, /* 20 */ 174 | {9, 19, 21, 55, 61, 69, 105, 111, 121, 129}, /* 21 */ 175 | {3, 17, 27, 33, 57, 87, 105, 113, 117, 123}, /* 22 */ 176 | {15, 21, 27, 37, 61, 69, 135, 147, 157, 159}, /* 23 */ 177 | {3, 17, 33, 63, 75, 77, 89, 95, 117, 167}, /* 24 */ 178 | {39, 49, 61, 85, 91, 115, 141, 159, 165, 183}, /* 25 */ 179 | {5, 27, 45, 87, 101, 107, 111, 117, 125, 135}, /* 26 */ 180 | {39, 79, 111, 115, 135, 187, 199, 219, 231, 235}, /* 27 */ 181 | {57, 89, 95, 119, 125, 143, 165, 183, 213, 273}, /* 28 */ 182 | {3, 33, 43, 63, 73, 75, 93, 99, 121, 133}, /* 29 */ 183 | {35, 41, 83, 101, 105, 107, 135, 153, 161, 173}, /* 30 */ 184 | {1, 19, 61, 69, 85, 99, 105, 151, 159, 171}, /* 31 */ 185 | {5, 17, 65, 99, 107, 135, 153, 185, 209, 267}, /* 32 */ 186 | {9, 25, 49, 79, 105, 285, 301, 303, 321, 355}, /* 33 */ 187 | {41, 77, 113, 131, 143, 165, 185, 207, 227, 281}, /* 34 */ 188 | {31, 49, 61, 69, 79, 121, 141, 247, 309, 325}, /* 35 */ 189 | {5, 17, 23, 65, 117, 137, 159, 173, 189, 233}, /* 36 */ 190 | {25, 31, 45, 69, 123, 141, 199, 201, 351, 375}, /* 37 */ 191 | {45, 87, 107, 131, 153, 185, 191, 227, 231, 257}, /* 38 */ 192 | {7, 19, 67, 91, 135, 165, 219, 231, 241, 301}, /* 39 */ 193 | {87, 167, 195, 203, 213, 285, 293, 299, 389, 437}, /* 40 */ 194 | {21, 31, 55, 63, 73, 75, 91, 111, 133, 139}, /* 41 */ 195 | {11, 17, 33, 53, 65, 143, 161, 165, 215, 227}, /* 42 */ 196 | {57, 67, 117, 175, 255, 267, 291, 309, 319, 369}, /* 43 */ 197 | {17, 117, 119, 129, 143, 149, 287, 327, 359, 377}, /* 44 */ 198 | {55, 69, 81, 93, 121, 133, 139, 159, 193, 229}, /* 45 */ 199 | {21, 57, 63, 77, 167, 197, 237, 287, 305, 311}, /* 46 */ 200 | {115, 127, 147, 279, 297, 339, 435, 541, 619, 649}, /* 47 */ 201 | {59, 65, 89, 93, 147, 165, 189, 233, 243, 257}, /* 48 */ 202 | {81, 111, 123, 139, 181, 201, 213, 265, 283, 339}, /* 49 */ 203 | {27, 35, 51, 71, 113, 117, 131, 161, 195, 233}, /* 50 */ 204 | {129, 139, 165, 231, 237, 247, 355, 391, 397, 439}, /* 51 */ 205 | {47, 143, 173, 183, 197, 209, 269, 285, 335, 395}, /* 52 */ 206 | {111, 145, 231, 265, 315, 339, 343, 369, 379, 421}, /* 53 */ 207 | {33, 53, 131, 165, 195, 245, 255, 257, 315, 327}, /* 54 */ 208 | {55, 67, 99, 127, 147, 169, 171, 199, 207, 267}, /* 55 */ 209 | {5, 27, 47, 57, 89, 93, 147, 177, 189, 195}, /* 56 */ 210 | {13, 25, 49, 61, 69, 111, 195, 273, 363, 423}, /* 57 */ 211 | {27, 57, 63, 137, 141, 147, 161, 203, 213, 251}, /* 58 */ 212 | {55, 99, 225, 427, 517, 607, 649, 687, 861, 871}, /* 59 */ 213 | {93, 107, 173, 179, 257, 279, 369, 395, 399, 453}, /* 60 */ 214 | {1, 31, 45, 229, 259, 283, 339, 391, 403, 465}, /* 61 */ 215 | {57, 87, 117, 143, 153, 167, 171, 195, 203, 273}, /* 62 */ 216 | {25, 165, 259, 301, 375, 387, 391, 409, 457, 471}, /* 63 */ 217 | {59, 83, 95, 179, 189, 257, 279, 323, 353, 363}}; /* 64 */ 218 | 219 | PrimeSieve(1000000); 220 | for (int func = 0; func < 4; func++) { 221 | // Try on first 1000000 numbers, compared to prime sieve. 222 | for (int n = 0; n <= 1000000; n++) { 223 | if (CallIsPrime(func, n) != prime[n]) { 224 | fail_test("IsPrimeFast", "Small prime test mismatch."); 225 | } 226 | } 227 | 228 | // Try on random slices of 100000 numbers, compared to Lehmer Pi count. 229 | for (int ntest = 0; ntest < 10; ntest++) { 230 | uint64 x = rand()%1000000000; 231 | int cum = 0; 232 | for (int i = 0; i <= 100000; i++) cum += CallIsPrime(func, x+i); 233 | if (cum != CountPrimes(x+100000) - CountPrimes(x-1)) { 234 | fail_test("IsPrimeFast", "Incorrect prime count"); 235 | } 236 | } 237 | 238 | // Try on some "hard" pseudoprimes from OEIS. 239 | for (int i = 0; i < sizeof(A014233)/sizeof(uint64); i++) { 240 | if (A014233[i] <= limits[func] && CallIsPrime(func, A014233[i])) { 241 | fail_test("IsPrimeFast", "Fooled by pseudoprime"); 242 | } 243 | } 244 | 245 | // Match up with known list of primes just under each power of 2. 246 | for (int i = 8; i <= 64; i++) { 247 | uint64 first = (i==64) ? -1 : (1LL< a4, b4; 272 | for (int i = 0; i < 1000; i++) { 273 | long long x = rand()-RAND_MAX/2; 274 | long long y = rand()-RAND_MAX/2; 275 | a1 = x; b1 = y; 276 | a2 = x; b2 = y; 277 | a3 = x; b3 = y; 278 | a4 = x; b4 = y; 279 | if ((a1*b1).toint() != x*y) fail_test("BigInt", "bigint mult"); 280 | if ((a2*b2).toint() != x*y) fail_test("BigInt", "binarybigint mult"); 281 | if ((a3*b3).toint() != x*y) fail_test("BigInt", "hexbigint mult"); 282 | if ((a4*b4).toint() != x*y) fail_test("BigInt", "single-digit bigint mult"); 283 | } 284 | } 285 | 286 | int main() { 287 | srand(time(0)); 288 | TEST_PokerHand(); 289 | TEST_IsPrimeFast(); 290 | TEST_BigInt(); 291 | } 292 | -------------------------------------------------------------------------------- /macros.h: -------------------------------------------------------------------------------- 1 | #ifndef __MACROS_H 2 | #define __MACROS_H 3 | 4 | //// Standard typedefs and Macros. Formatted for process.exe. 5 | 6 | //// *** Typedefs *** 7 | 8 | typedef signed long long int64; 9 | typedef unsigned long long uint64; 10 | typedef vector VI; 11 | typedef vector VVI; 12 | typedef vector VC; 13 | typedef vector VVC; 14 | typedef vector VS; 15 | typedef vector VVS; 16 | typedef vector VD; 17 | typedef vector VVD; 18 | typedef vector VLL; 19 | typedef vector VVLL; 20 | typedef vector > VPII; 21 | typedef pair PII; 22 | typedef pair > PIPII; 23 | 24 | //// *** Macros *** 25 | 26 | #define ALL(s) s.begin(), s.end() 27 | #define FORALL(s,i) for (auto i=s.begin(); i != s.end(); ++i) 28 | #define FORALLBITS(x,i) for (int xTmP=(x),i; (i=__builtin_ffs(xTmP)-1)>-1; xTmP&=xTmP-1) 29 | 30 | //// *** Constants *** 31 | 32 | #define PI 3.14159265358979323846 33 | #define EPS 1e-9 34 | #define INF __builtin_inf() 35 | 36 | //// *** Bitwise functions *** 37 | 38 | inline int BitCount(unsigned x) {return __builtin_popcount(x);} 39 | 40 | inline int BitCountLL(unsigned long long x) {return __builtin_popcountll(x);} 41 | 42 | inline unsigned LowestBit(unsigned x) {return x & ~(x-1);} 43 | 44 | inline unsigned long long LowestBitLL(unsigned long long x) {return x & ~(x-1);} 45 | 46 | inline unsigned ClearLowestBit(unsigned x) {return x & (x-1);} 47 | 48 | inline unsigned long long ClearLowestBitLL(unsigned long long x) {return x & (x-1);} 49 | 50 | inline int LowestBitIndex(unsigned x) {return __builtin_ffs(x)-1;} 51 | 52 | inline int LowestBitIndexLL(unsigned long long x) {return __builtin_ffsll(x)-1;} 53 | 54 | #endif // __MACROS_H 55 | -------------------------------------------------------------------------------- /math.h: -------------------------------------------------------------------------------- 1 | #ifndef __MATH_H 2 | #define __MATH_H 3 | 4 | //// Advanced math functions. Formatted for process.exe. 5 | 6 | //// Modular functions 7 | 8 | inline unsigned ModMult(unsigned a, unsigned b, unsigned m) { 9 | return (uint64)a*b%m; 10 | } 11 | 12 | unsigned ModPow(unsigned a, uint64 b, unsigned m) { 13 | unsigned ret = (m>1); 14 | for(;;) { 15 | if (b&1) ret = ModMult(ret, a, m); 16 | if (!(b>>=1)) return ret; 17 | a = ModMult(a, a, m); 18 | } 19 | } 20 | 21 | inline unsigned ModInv(unsigned a, unsigned p) { // Works for prime p only. 22 | return ModPow(a, p-2, p); 23 | } 24 | 25 | inline uint64 ModMult48(uint64 a, uint64 b, uint64 m) { // Requires m < 2^42. 26 | uint64 ahi = (a>>21); 27 | uint64 alo = (a&0x1fffff); 28 | uint64 rethi = (ahi*b)%m; 29 | return ((rethi<<21) + alo*b)%m; 30 | } 31 | 32 | uint64 ModPow48(uint64 a, uint64 b, uint64 m) { // Requires m < 2^42. 33 | uint64 ret = (m>1); 34 | for(;;) { 35 | if (b&1) ret = ModMult48(ret, a, m); 36 | if (!(b>>=1)) return ret; 37 | a = ModMult48(a, a, m); 38 | } 39 | } 40 | 41 | inline uint64 ModInv48(uint64 a, uint64 p) { // Requires prime p < 2^42. 42 | return ModPow48(a, p-2, p); 43 | } 44 | 45 | inline uint64 ModMult64(uint64 a, uint64 b, uint64 m) { 46 | uint64 hi, lo; 47 | Mult128(a, b, hi, lo); 48 | for (int i = 0; i < 64; i++) { 49 | bool car = (hi>>63); 50 | hi = (hi<<1) | (lo >> 63); 51 | lo <<= 1; 52 | if (car || hi >= m) hi -= m; 53 | } 54 | return hi; 55 | } 56 | 57 | uint64 ModPow64(uint64 a, uint64 b, uint64 m) { 58 | uint64 ret = (m>1); 59 | for(;;) { 60 | if (b&1) ret = ModMult64(ret, a, m); 61 | if (!(b>>=1)) return ret; 62 | a = ModMult64(a, a, m); 63 | } 64 | } 65 | 66 | inline uint64 ModInv64(uint64 a, uint64 p) { // Requires prime p. 67 | return ModPow64(a, p-2, p); 68 | } 69 | 70 | //// *** Primality and Factoring *** 71 | 72 | template T Gcd(const T& a, const T& b) { 73 | return b != T() ? Gcd(b, a%b) : abs(a); 74 | } 75 | 76 | vector prime; 77 | void PrimeSieve(int limit) { 78 | prime = vector(limit+1, true); 79 | prime[0] = prime[1] = false; 80 | for (int x = 2; x*x <= limit; x++) if (prime[x]) { 81 | int inc = (x==2) ? x : 2*x; 82 | for (int y = x*x; y <= limit; y += inc) { 83 | prime[y] = false; 84 | } 85 | } 86 | } 87 | 88 | bool IsPrime(uint64 n) { 89 | if (n <= 3) return n > 1; 90 | if ((n&1) == 0 || n%3 == 0) return false; 91 | for (uint64 x = 5, xsq = 5*5, xsqd = 11*11 - 5*5; xsq > 0 && xsq <= n; 92 | x += 6, xsq += xsqd, xsqd += (17*17-11*11) - (11*11-5*5)) 93 | if (n%x == 0 || n%(x+2) == 0) return false; 94 | return true; 95 | } 96 | 97 | // Works for all primes p < 2^32. 98 | bool IsPrimeFast(unsigned n) { 99 | if (n <= 3) return (n >= 2); 100 | static const unsigned small[] = 101 | {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67}; 102 | for (int i = 0; i < sizeof(small)/sizeof(unsigned); i++) { 103 | if (n%small[i] == 0) return n == small[i]; 104 | } 105 | 106 | // Jaeschke93 showed that 2,7,61 suffice for n < 4,759,123,141. 107 | static const unsigned millerrabin[] = {2, 7, 61}; 108 | unsigned s = n-1, r = 0; 109 | while (s%2 == 0) {s /= 2; r++;} 110 | for (int i = 0, j; i < sizeof(millerrabin)/sizeof(unsigned); i++) { 111 | unsigned md = ModPow(millerrabin[i], s, n); 112 | if (md == 1) continue; 113 | for (j = 1; j < r; j++) { 114 | if (md == n-1) break; 115 | md = ModMult(md, md, n); 116 | } 117 | if (md != n-1) return false; 118 | } 119 | 120 | return true; 121 | } 122 | 123 | // Works for all primes p < 2^42. 124 | bool IsPrimeFast48(uint64 n) { 125 | if (n <= 3) return (n >= 2); 126 | static const uint64 small[] = 127 | {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 128 | 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139}; 129 | for (int i = 0; i < sizeof(small)/sizeof(uint64); i++) { 130 | if (n%small[i] == 0) return n == small[i]; 131 | } 132 | 133 | if (n == 17431) return true; 134 | if (n == 3281359) return true; 135 | // These values, valid for n < 21,652,684,502,221, were found by Steve Worley. 136 | static const uint64 millerrabin[] = {2, 1215, 34862, 574237825}; 137 | uint64 s = n-1, r = 0; 138 | while (s%2 == 0) {s /= 2; r++;} 139 | for (int i = 0, j; i < sizeof(millerrabin)/sizeof(uint64); i++) { 140 | uint64 md = ModPow48(millerrabin[i], s, n); 141 | if (md == 1) continue; 142 | for (j = 1; j < r; j++) { 143 | if (md == n-1) break; 144 | md = ModMult48(md, md, n); 145 | } 146 | if (md != n-1) return false; 147 | } 148 | 149 | return true; 150 | } 151 | 152 | // Works for all primes p < 2^64. 153 | bool IsPrimeFast64(uint64 n) { 154 | if (n <= 3) return (n >= 2); 155 | static const uint64 small[] = 156 | {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 157 | 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 158 | 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199}; 159 | for (int i = 0; i < sizeof(small)/sizeof(uint64); i++) { 160 | if (n%small[i] == 0) return n == small[i]; 161 | } 162 | 163 | // Makes use of the known bounds for Miller-Rabin pseudoprimes. 164 | static const uint64 millerrabin[] = 165 | {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; 166 | static const uint64 A014233[] = // From OEIS. 167 | {2047LL, 1373653LL, 25326001LL, 3215031751LL, 2152302898747LL, 168 | 3474749660383LL, 341550071728321LL, 341550071728321LL, 169 | 3825123056546413051LL, 3825123056546413051LL, 3825123056546413051LL, 0}; 170 | uint64 s = n-1, r = 0; 171 | while (s%2 == 0) {s /= 2; r++;} 172 | for (int i = 0, j; i < sizeof(millerrabin)/sizeof(uint64); i++) { 173 | uint64 md = ModPow64(millerrabin[i], s, n); 174 | if (md != 1) { 175 | for (j = 1; j < r; j++) { 176 | if (md == n-1) break; 177 | md = ModMult64(md, md, n); 178 | } 179 | if (md != n-1) return false; 180 | } 181 | if (n < A014233[i]) return true; 182 | } 183 | 184 | return true; 185 | } 186 | 187 | vector PrimeFactors(int n) { 188 | vector ret; 189 | while ((n&1) == 0) {ret.push_back(2); n /= 2;} 190 | while (n%3 == 0) {ret.push_back(3); n /= 3;} 191 | for (int x = 5, xsq = 5*5, xsqd = 11*11 - 5*5; xsq > 0 && xsq <= n; 192 | x += 6, xsq += xsqd, xsqd += (17*17-11*11) - (11*11-5*5)) { 193 | while (n%x == 0) {ret.push_back(x); n /= x;} 194 | while (n%(x+2)==0) {ret.push_back(x+2); n /= x+2;} 195 | } 196 | if (n > 1) ret.push_back(n); 197 | return ret; 198 | } 199 | 200 | vector UniquePrimeFactors(int n) { 201 | vector ret; 202 | if ((n&1) == 0) {ret.push_back(2); do {n /= 2;} while ((n&1) == 0);} 203 | if (n%3 == 0) {ret.push_back(3); do {n /= 3;} while (n%3 == 0);} 204 | for (int x = 5, xsq = 5*5, xsqd = 11*11 - 5*5; xsq > 0 && xsq <= n; 205 | x += 6, xsq += xsqd, xsqd += (17*17-11*11) - (11*11-5*5)) { 206 | if (n%x == 0) {ret.push_back(x); do {n /= x;} while (n%x == 0);} 207 | if (n%(x+2)==0) {ret.push_back(x+2); do {n /= x+2;} while (n%(x+2) == 0);} 208 | } 209 | if (n > 1) ret.push_back(n); 210 | return ret; 211 | } 212 | 213 | // Count of x, 1 <= x <= n, such that Gcd(x, n) == 1. 214 | // Requires factoring to compute. 215 | int EulerPhi(int n) { 216 | int ret = n; 217 | if ((n&1) == 0) {ret >>= 1; do {n /= 2;} while ((n&1) == 0);} 218 | if (n%3 == 0) {ret /= 3; ret *= 2; do {n /= 3;} while (n%3 == 0);} 219 | for (int x = 5, xsq = 5*5, xsqd = 11*11 - 5*5; xsq > 0 && xsq <= n; 220 | x += 6, xsq += xsqd, xsqd += (17*17-11*11) - (11*11-5*5)) { 221 | if (n%x == 0) {ret /= x; ret *= x-1; do {n /= x;} while (n%x == 0);} 222 | if (n%(x+2)==0) {ret /= x+2; ret *= x+1; do {n /= x+2;} while (n%(x+2) == 0);} 223 | } 224 | if (n > 1) {ret /= n; ret *= n-1;} 225 | return ret; 226 | } 227 | 228 | // Lehmer's method for counting primes p, 2 <= p <= x. 229 | vector cumprime, primelist(1); 230 | uint64 CountPrimes(uint64 x); 231 | uint64 CountPrimes_Phi(uint64 m, int pi) { 232 | if (primelist[pi]*primelist[pi] > m) return CountPrimes(m)-(pi-1); 233 | uint64 ret = m; 234 | for (; pi > 0; pi--) ret -= CountPrimes_Phi(m/primelist[pi], pi-1); 235 | return ret; 236 | } 237 | uint64 CountPrimes(uint64 x) { 238 | #define COUNTPRIME__MAX 1e13 239 | if (cumprime.size() == 0) { 240 | if (prime.size() < sqrt(COUNTPRIME__MAX)) PrimeSieve(sqrt(COUNTPRIME__MAX)); 241 | cumprime.resize(prime.size()); 242 | for (int i = 1; i < prime.size(); i++) { 243 | cumprime[i] = cumprime[i-1] + prime[i]; 244 | if (prime[i]) primelist.push_back(i); 245 | } 246 | } 247 | if (x < cumprime.size()) return cumprime[x]; 248 | int a = cumprime[pow(x, 1/4.0)]; 249 | int b = cumprime[pow(x, 1/2.0)]; 250 | int c = cumprime[pow(x, 1/3.0)]+1; 251 | uint64 ret = CountPrimes_Phi(x, a) + (uint64)(b+a-2)*(b-a+1)/2; 252 | for (int i = a+1; i <= b; i++) { 253 | uint64 d = x / primelist[i]; 254 | ret -= CountPrimes(d); 255 | if (i <= c) { 256 | int bi = cumprime[sqrt(d)]; 257 | for (int j = i; j <= bi; j++) ret -= CountPrimes(d/primelist[j]) - (j-1); 258 | } 259 | } 260 | return ret; 261 | } 262 | 263 | //// *** Combinations/Permutations *** 264 | 265 | int Comb(int a, int b) { 266 | #define COMB__MAXA 1000 267 | #define COMB__MAXB 1000 268 | if (b > a || b < 0) return 0; 269 | if (!a) return 1; 270 | static int combmemo[COMB__MAXA+1][COMB__MAXB+1]; 271 | int &ret = combmemo[a][b]; 272 | if (!ret) ret = Comb(a-1, b-1)+Comb(a-1,b); 273 | return ret; 274 | } 275 | 276 | //// *** Large numbers *** 277 | 278 | void Mult128(uint64 a, uint64 b, uint64& hi, uint64& lo) { 279 | uint64 ahi = (a>>32), alo = (a&0xffffffffLL); 280 | uint64 bhi = (b>>32), blo = (b&0xffffffffLL); 281 | hi = alo*blo; 282 | lo = (hi&0xffffffffLL); 283 | hi >>= 32; 284 | uint64 x = alo*bhi, y = ahi*blo; 285 | hi += x+y; 286 | uint64 car = (hi < y); 287 | lo |= (hi&0xffffffffLL)<<32; 288 | hi >>= 32; 289 | hi += ahi*bhi + (car<<32); 290 | } 291 | 292 | #endif // __MATH_H 293 | -------------------------------------------------------------------------------- /mathtypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __MATHTYPES_H 2 | #define __MATHTYPES_H 3 | 4 | //// Special structures that can be manipulated like numbers. 5 | //// Formatted for process.exe. 6 | 7 | //// *** Integer with constant modulus *** 8 | 9 | // Note: MOD should be < 2^30. If division is used, MOD must be prime. 10 | template struct ModInt { 11 | int value; 12 | ModInt() : value(0) {} 13 | ModInt(int v) : value(v % MOD) {} 14 | ModInt(long long v) : value(v % MOD) {} 15 | ModInt Pow(int b) const { 16 | ModInt ret, a; ret.value = (MOD!=1); a.value = value; 17 | for(;;) {if (b&1) ret *= a; if (!(b>>=1)) return ret; a *= a;} 18 | } 19 | ModInt Inverse() const { return Pow(MOD-2); } 20 | ModInt operator+(const ModInt& m) const {return value+m.value;} 21 | ModInt& operator+=(const ModInt& m) {value = (value+m.value) % MOD; return *this;} 22 | ModInt operator-(const ModInt& m) const {return value-m.value;} 23 | ModInt& operator-=(const ModInt& m) {value = (value-m.value) % MOD; return *this;} 24 | ModInt operator-() const {return -value;} 25 | ModInt operator*(const ModInt& m) const {return (long long)value*m.value;} 26 | ModInt& operator*=(const ModInt& m) {value = ((long long)value*m.value) % MOD; return *this;} 27 | ModInt operator/(const ModInt& m) const {return *this * m.Inverse();} 28 | ModInt& operator/=(const ModInt& m) {return *this *= m.Inverse();} 29 | bool operator==(const ModInt& m) const {return toint() == m.toint();} 30 | bool operator!=(const ModInt& m) const {return toint() != m.toint();} 31 | int toint() const {return (value < 0) ? value + MOD : value;} 32 | friend ostream& operator<<(ostream& out, const ModInt& m) {out << m.toint(); return out;} 33 | }; 34 | 35 | //// *** Fraction class *** 36 | 37 | template struct Fract { 38 | T n, d; 39 | Fract(const T& n=0) : n(n), d(1) {} 40 | Fract(const T& n, const T& d, bool reduce=true) : n(n), d(d) {if (reduce) Reduce();} 41 | void Reduce() {if (d < 0) {n = -n; d = -d;} T g = Gcd(n, d); if (g != 1) {n /= g; d /= g;}} 42 | Fract operator+(const Fract& f) const {return Fract(n*f.d+f.n*d, d*f.d);} 43 | Fract& operator+=(const Fract& f) {n = n*f.d+f.n*d; d *= f.d; Reduce(); return *this;} 44 | Fract operator-(const Fract& f) const {return Fract(n*f.d-f.n*d, d*f.d);} 45 | Fract& operator-=(const Fract& f) {n = n*f.d-f.n*d; d *= f.d; Reduce(); return *this;} 46 | Fract operator-() const {return Fract(-n, d, false);} 47 | Fract operator*(const Fract& f) const {return Fract(n*f.n, d*f.d);} 48 | Fract& operator*=(const Fract& f) {n *= f.n; d *= f.d; Reduce(); return *this;} 49 | Fract operator/(const Fract& f) const {return Fract(n*f.d, d*f.n);} 50 | Fract& operator/=(const Fract& f) {n *= f.d; d *= f.n; Reduce(); return *this;} 51 | bool operator<(const Fract& f) const {return n*f.d < d*f.n;} 52 | bool operator<=(const Fract& f) const {return n*f.d <= d*f.n;} 53 | bool operator>(const Fract& f) const {return n*f.d > d*f.n;} 54 | bool operator>=(const Fract& f) const {return n*f.d >= d*f.n;} 55 | bool operator==(const Fract& f) const {return n == f.n && d == f.d;} 56 | bool operator!=(const Fract& f) const {return n != f.n || d != f.d;} 57 | double todouble() const {return (double)n/(double)d;} 58 | friend Fract abs(const Fract& f) {return Fract(abs(f.n), f.d, false);} 59 | friend ostream& operator<<(ostream& out, const Fract& f) {out << f.n; if (f.d != 1) out << '/' << f.d; return out;} 60 | }; 61 | 62 | //// *** Polynomial class *** 63 | 64 | template struct Polynomial { 65 | vector co; 66 | Polynomial() : co() {} 67 | Polynomial(const T& x) : co(1, x) {Simplify();} 68 | Polynomial(const T& x, const T& y) : co(2) {co[1] = x; co[0] = y; Simplify();} 69 | Polynomial(const vector& v) : co(v) {Simplify();} 70 | T Eval(const T& x) const {T ret = T(); for (int i = co.size()-1; i >= 0; i--) {ret *= x; ret += co[i];} return ret;} 71 | void Simplify() {while (co.size() && co.back() == T()) co.pop_back();} 72 | Polynomial operator+(const Polynomial& p) const {Polynomial ret = *this; return ret += p;} 73 | Polynomial& operator+=(const Polynomial& p) { 74 | if (p.co.size() > co.size()) co.resize(p.co.size()); 75 | for (int i = 0; i < p.co.size(); i++) co[i] += p.co[i]; 76 | Simplify(); 77 | return *this; 78 | } 79 | Polynomial operator-(const Polynomial& p) const {Polynomial ret = *this; return ret -= p;} 80 | Polynomial& operator-=(const Polynomial& p) { 81 | if (p.co.size() > co.size()) co.resize(p.co.size()); 82 | for (int i = 0; i < p.co.size(); i++) co[i] -= p.co[i]; 83 | Simplify(); 84 | return *this; 85 | } 86 | Polynomial operator-() const 87 | {Polynomial ret = *this; for (int i = 0; i < ret.co.size(); i++) ret.co[i] = -ret.co[i]; return ret;} 88 | Polynomial operator*(const T& x) const {Polynomial ret = *this; return ret *= x;} 89 | Polynomial& operator*=(const T& x) {for (int i = 0; i < co.size(); i++) co[i] *= x; Simplify(); return *this;} 90 | Polynomial operator/(const T& x) const {Polynomial ret = *this; return ret /= x;} 91 | Polynomial& operator/=(const T& x) {for (int i = 0; i < co.size(); i++) co[i] /= x; Simplify(); return *this;} 92 | Polynomial operator*(const Polynomial& p) const { 93 | if (!co.size() || !p.co.size()) return Polynomial(); 94 | Polynomial ret; 95 | ret.co.resize(co.size() + p.co.size() - 1); 96 | for (int i = 0; i < co.size(); i++) 97 | for (int j = 0; j < p.co.size(); j++) 98 | ret.co[i+j] += co[i] * p.co[j]; 99 | ret.Simplify(); 100 | return ret; 101 | } 102 | Polynomial& operator*=(const Polynomial& p) {*this = *this * p; return *this;} 103 | friend ostream& operator<<(ostream& out, const Polynomial& p) { 104 | if (!p.co.size()) {out << 0; return out;} 105 | for (int i = p.co.size()-1; i >= 0; i--) if (p.co[i] != T()) { 106 | if (i < p.co.size()-1 || p.co[i] < 0) out << ((p.co[i] < 0) ? '-' : '+'); 107 | if (abs(p.co[i]) != T(1) || i == 0) out << abs(p.co[i]); 108 | if (i > 0) out << 'x'; 109 | if (i > 1) out << '^' << i; 110 | } 111 | return out; 112 | } 113 | }; 114 | 115 | template Polynomial PolynomialDerivative(const Polynomial& p) { 116 | Polynomial ret; 117 | for (int i = 1; i < p.co.size(); i++) 118 | ret.co.push_back(p.co[i] * i); 119 | ret.Simplify(); 120 | return ret; 121 | } 122 | 123 | // Note: Returns the integral with constant coefficient 0. 124 | template Polynomial PolynomialIntegral(const Polynomial& p) { 125 | Polynomial ret; 126 | ret.co.push_back(T()); 127 | for (int i = 0; i < p.co.size(); i++) 128 | ret.co.push_back(p.co[i] / (i+1)); 129 | ret.Simplify(); 130 | return ret; 131 | } 132 | 133 | template Polynomial PolynomialSubstitute(const Polynomial& p, const Polynomial& x) { 134 | Polynomial xpow(1), ret; 135 | for (int i = 0; i < p.co.size(); i++) { 136 | if (i) xpow *= x; 137 | ret += xpow * p.co[i]; 138 | } 139 | ret.Simplify(); 140 | return ret; 141 | } 142 | 143 | // Note: T must support division. 144 | template Polynomial PolynomialSum0ToX(const Polynomial& p) { 145 | static vector > powers_of_x_plus_one; 146 | static vector > power_sums; 147 | if (powers_of_x_plus_one.size() == 0) 148 | powers_of_x_plus_one.push_back(Polynomial(1)); 149 | if (powers_of_x_plus_one.size() == 1) 150 | powers_of_x_plus_one.push_back(Polynomial(vector(2, 1))); 151 | for (int i = powers_of_x_plus_one.size(); i <= p.co.size(); i++) 152 | powers_of_x_plus_one.push_back(powers_of_x_plus_one[i-1] * 153 | powers_of_x_plus_one[1]); 154 | for (int n = power_sums.size(); n < p.co.size(); n++) { 155 | power_sums.push_back(powers_of_x_plus_one[n+1]); 156 | for (int i = 0; i < n; i++) 157 | power_sums.back() -= power_sums[i] * powers_of_x_plus_one[n+1].co[i]; 158 | for (int i = 0; i <= n+1; i++) 159 | power_sums.back().co[i] /= n+1; 160 | } 161 | Polynomial ret; 162 | for (int i = 0; i < p.co.size(); i++) ret += power_sums[i] * p.co[i]; 163 | return ret; 164 | } 165 | 166 | template string PolynomialToString(const Polynomial& p) { 167 | ostringstream out; 168 | out << p; 169 | return out.str(); 170 | } 171 | 172 | //// *** BigInts *** 173 | 174 | // A string-based BigInt. Straightforward but rather slow. 175 | struct SimpleBigInt { 176 | bool neg; 177 | string dig; 178 | SimpleBigInt() : dig("0"), neg(false) {} 179 | SimpleBigInt(int x) 180 | {if ((neg=x<0)) x=-x; do {dig.push_back(x%10+'0'); x /= 10;} while (x); reverse(dig.begin(), dig.end());} 181 | SimpleBigInt(long long x) 182 | {if ((neg=x<0)) x=-x; do {dig.push_back(x%10+'0'); x /= 10;} while (x); reverse(dig.begin(), dig.end());} 183 | SimpleBigInt(const string& s) {if ((neg=(s[0]=='-'))) dig = s.substr(1); else dig = s;} 184 | SimpleBigInt(const string& dig, bool neg) : dig(dig), neg(neg) {} 185 | static bool LessThan(const string& a, bool an, const string& b, bool bn, bool count_eq) { 186 | if (an != bn) return an; 187 | if (a.size() != b.size()) return (a.size() < b.size()) ^ an; 188 | for (int i = 0; i < a.size(); i++) if (a[i] != b[i]) return (a[i] < b[i]) ^ an; 189 | return count_eq; 190 | } 191 | static SimpleBigInt AddOrSubtract(const string& a, bool an, const string& b, bool bn) { 192 | SimpleBigInt ret("", an); 193 | if (an == bn) { 194 | for (int i = 0, c = 0; i < a.size() || i < b.size() || c; i++) { 195 | if (i < a.size()) c += a[a.size()-1-i]-'0'; 196 | if (i < b.size()) c += b[b.size()-1-i]-'0'; 197 | ret.dig += c%10 + '0'; c /= 10; 198 | } 199 | } else { 200 | bool swp = LessThan(a, false, b, false, an); 201 | if (swp) ret.neg = bn; 202 | const string& s1 = (swp ? b : a), s2 = (swp ? a : b); 203 | for (int i = 0, c = 0; i < s1.size(); i++) { 204 | c += 10 + s1[s1.size()-1-i]-'0'; 205 | if (i < s2.size()) c -= s2[s2.size()-1-i]-'0'; 206 | ret.dig += c%10 + '0'; c = c/10-1; 207 | } 208 | for (int i = ret.dig.size()-1; i >= 0; i--) 209 | if (i==0 || ret.dig[i]!='0') {ret.dig = ret.dig.substr(0, i+1); break;} 210 | } 211 | reverse(ret.dig.begin(), ret.dig.end()); 212 | return ret; 213 | } 214 | SimpleBigInt operator+(const SimpleBigInt& b) const {return AddOrSubtract(dig, neg, b.dig, b.neg);} 215 | SimpleBigInt& operator+=(const SimpleBigInt& b) {*this = AddOrSubtract(dig, neg, b.dig, b.neg); return *this;} 216 | SimpleBigInt operator-(const SimpleBigInt& b) const {return AddOrSubtract(dig, neg, b.dig, !b.neg);} 217 | SimpleBigInt& operator-=(const SimpleBigInt& b) {*this = AddOrSubtract(dig, neg, b.dig, !b.neg); return *this;} 218 | SimpleBigInt operator-() const {return SimpleBigInt(dig, !(neg || dig=="0"));} 219 | SimpleBigInt operator*(int x) const { // NOTE: x*10 should not overflow int. 220 | if (x == 0) return SimpleBigInt(); 221 | SimpleBigInt ret("", neg); 222 | if (x < 0) {x = -x; ret.neg = !neg && dig != "0";} 223 | for (int i = 0, c = 0; i < dig.size() || c; i++) { 224 | if (i < dig.size()) c += x * (dig[dig.size()-1-i]-'0'); 225 | ret.dig += c%10 + '0'; c /= 10; 226 | } 227 | reverse(ret.dig.begin(), ret.dig.end()); 228 | return ret; 229 | } 230 | SimpleBigInt& operator*=(int x) {return *this = *this * x;} 231 | SimpleBigInt operator*(const SimpleBigInt& b) const { 232 | if (b == 0 || *this == 0) return SimpleBigInt(); 233 | SimpleBigInt ret; 234 | for (int i = 0; i < b.dig.size(); i++) { 235 | char ch = b.dig[b.dig.size()-1-i]; 236 | if (ch == '0') continue; 237 | SimpleBigInt v = *this * (int)(ch-'0'); 238 | for (int j = 0; j < i; j++) v.dig += '0'; 239 | ret += v; 240 | } 241 | if (b.neg) ret.neg = !ret.neg; 242 | return ret; 243 | } 244 | SimpleBigInt& operator*=(const SimpleBigInt& b) {return *this = *this * b;} 245 | SimpleBigInt operator/(SimpleBigInt b) const { 246 | if (b == 0 || *this == 0) return SimpleBigInt(); 247 | SimpleBigInt ret("", neg ^ b.neg), rem(dig, false); 248 | b.neg = false; 249 | int d = 0; 250 | while (b <= rem) {b.dig += '0'; d++;} 251 | if (d == 0) return SimpleBigInt(); 252 | ret.dig = string(d, '0'); 253 | for (d--; d >= 0; d--) { 254 | b.dig.resize(b.dig.size()-1); 255 | while (b <= rem) {rem -= b; ret.dig[ret.dig.size()-1-d]++;} 256 | } 257 | return ret; 258 | } 259 | SimpleBigInt& operator/=(const SimpleBigInt& b) {return *this = *this / b;} 260 | SimpleBigInt operator%(const SimpleBigInt& b) const {return *this - b * (*this / b);} 261 | SimpleBigInt& operator%=(const SimpleBigInt& b) {return *this -= b * (*this / b);} 262 | bool operator<(const SimpleBigInt& b) const {return LessThan(dig, neg, b.dig, b.neg, false);} 263 | bool operator<=(const SimpleBigInt& b) const {return LessThan(dig, neg, b.dig, b.neg, true);} 264 | bool operator>(const SimpleBigInt& b) const {return !LessThan(dig, neg, b.dig, b.neg, true);} 265 | bool operator>=(const SimpleBigInt& b) const {return !LessThan(dig, neg, b.dig, b.neg, false);} 266 | bool operator==(const SimpleBigInt& b) const {return neg == b.neg && dig == b.dig;} 267 | bool operator!=(const SimpleBigInt& b) const {return neg != b.neg || dig != b.dig;} 268 | string tostring() const {return (neg ? "-" : "") + dig;} 269 | friend SimpleBigInt abs(const SimpleBigInt& b) {return SimpleBigInt(b.dig, false);} 270 | friend istream& operator>>(istream& in, SimpleBigInt& b) {string s; in >> s; b = SimpleBigInt(s); return in;} 271 | friend ostream& operator<<(ostream& out, const SimpleBigInt& b) {if (b.neg) out << '-'; out << b.dig; return out;} 272 | }; 273 | 274 | // Copyright (c) Derek Kisman (SnapDragon) dkisman@gmail.com 275 | // You must ask permission to use my BigInt code in your contests 276 | const string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 277 | template 278 | struct BigInt { 279 | vector ch; 280 | bool neg; 281 | 282 | BigInt& operator+=(const BigInt& b) { 283 | int car = 0; unsigned x; 284 | for (int i = 0; i < ch.size() || i < b.ch.size(); i++) { 285 | x = CHUNKRADIX + car + ((i zeros; 310 | for (auto it = b.ch.begin(); it != b.ch.end(); it++) { 311 | BigInt b3 = b2 * *it; 312 | b3.ch.insert(b3.ch.begin(), zeros.begin(), zeros.end()); 313 | *this += b3; 314 | zeros.push_back(0); 315 | } 316 | if (b.neg && !zero()) neg = !neg; 317 | return *this; 318 | } 319 | inline BigInt operator*(const BigInt& b) const {return BigInt(*this)*=b;} 320 | BigInt& operator/=(BigInt b) { 321 | bool retneg = (b.neg) ? !neg : neg; 322 | b.neg = neg = false; 323 | if (b > *this || b.zero()) return (*this=BigInt()); 324 | if (b.ch.size() == 1) return (*this /= retneg ? -b.ch[0] : b.ch[0]); 325 | if (CHUNKRADIX >= (1<<21)) { 326 | int bm = CHUNKRADIX/b.ch.back() + 1; b *= bm; *this *= bm; 327 | } 328 | int64 p, q = (int64)CHUNKRADIX*b.ch.back() + b.ch[b.ch.size()-2]; 329 | vector ret(ch.size()-b.ch.size()+1); 330 | b.ch.insert(b.ch.begin(), ret.begin(), ret.end()); 331 | for (int i = ret.size()-1, j = ch.size()-1; i >= 0; i--, j--) { 332 | b.ch.erase(b.ch.begin()); 333 | if (j >= ch.size()) {ret[i] = 0; continue;} 334 | p = (int64)CHUNKRADIX*ch[j] + ch[j-1] + 1; 335 | if (j+1 < ch.size()) p += (int64)CHUNKRADIX*CHUNKRADIX*ch[j+1]; 336 | *this -= b*(ret[i] = p/q); 337 | while (neg) {*this += b; ret[i]--;} 338 | } 339 | ch = ret; neg = retneg; 340 | trim(); 341 | return *this; 342 | } 343 | inline BigInt operator/(const BigInt& b) const {return BigInt(*this)/=b;} 344 | inline BigInt& operator%=(const BigInt& b) {return *this -= (*this/b)*b;} 345 | inline BigInt operator%(const BigInt& b) const {return BigInt(*this)%=b;} 346 | BigInt& operator*=(int x) { 347 | if (!x || zero()) return (*this = BigInt()); 348 | neg ^= (x<0); 349 | uint64 car = 0, xl = abs(x); if (xl == 1) return *this; 350 | for (auto it = ch.begin(); it != ch.end(); it++) { 351 | car += *it * xl; 352 | *it = car%CHUNKRADIX; 353 | car /= CHUNKRADIX; 354 | } 355 | while (car) {ch.push_back(car%CHUNKRADIX); car /= CHUNKRADIX;} 356 | return *this; 357 | } 358 | inline BigInt operator*(int x) const {return BigInt(*this)*=x;} 359 | BigInt& operator/=(int x) { 360 | if (!x) {return *this = BigInt();} 361 | neg ^= (x<0); 362 | uint64 car = 0; x = abs(x); if (x == 1) return *this; 363 | for (auto it = ch.rbegin(); it != ch.rend(); it++) { 364 | car = CHUNKRADIX*car + *it; 365 | *it = car / x; 366 | car %= x; 367 | } 368 | trim(); 369 | return *this; 370 | } 371 | inline BigInt operator/(int x) const {return BigInt(*this)/=x;} 372 | int operator%(int x) const { 373 | int ret = 0; x = abs(x); 374 | auto it = ch.rbegin(); 375 | if (CHUNKRADIX%x == 0 && ch.size()) {it = --ch.rend();} 376 | for (; it != ch.rend(); it++) ret = ((uint64)CHUNKRADIX*ret + *it)%x; 377 | return neg ? -ret : ret; 378 | } 379 | 380 | bool operator<(const BigInt& b) const { 381 | if (neg != b.neg) return neg; 382 | if (ch.size() != b.ch.size()) return neg ^ (ch.size() < b.ch.size()); 383 | for (int i = ch.size()-1; i >= 0; i--) 384 | if (ch[i] != b.ch[i]) return neg ^ (ch[i] < b.ch[i]); 385 | return false; 386 | } 387 | bool operator<=(const BigInt& b) const { 388 | if (neg != b.neg) return neg; 389 | if (ch.size() != b.ch.size()) return neg ^ (ch.size() < b.ch.size()); 390 | for (int i = ch.size()-1; i >= 0; i--) 391 | if (ch[i] != b.ch[i]) return neg ^ (ch[i] < b.ch[i]); 392 | return true; 393 | } 394 | inline bool operator==(const BigInt& b) const 395 | {return neg==b.neg && ch==b.ch;} 396 | inline bool operator>(const BigInt& b) const {return !(*this <= b);} 397 | inline bool operator>=(const BigInt& b) const {return !(*this < b);} 398 | inline bool operator!=(const BigInt& b) const {return !(*this == b);} 399 | friend inline BigInt operator-(const BigInt& b) 400 | {BigInt ret(b); ret.neg = !ret.neg; return ret;} 401 | friend inline BigInt abs(const BigInt& b) {return b.neg ? -b : b;} 402 | 403 | size_t digits() const { 404 | if (ch.size() == 0) return 1; 405 | size_t ret = (ch.size()-1)*CHUNKSIZE; 406 | for (int x = ch.back(); x; x /= RADIX) ret++; 407 | return ret; 408 | } 409 | inline bool zero() const {return ch.size() == 0;} 410 | int64 toint() const { 411 | int64 ret = 0; 412 | for (auto it = ch.rbegin(); it != ch.rend(); it++) 413 | ret = ret*CHUNKRADIX + *it; 414 | return neg ? -ret : ret; 415 | } 416 | string tostring() const { 417 | if (ch.size() == 0) return "0"; 418 | auto it = ch.begin(); 419 | string ret; 420 | int i, x; 421 | while (it != ch.end()) { 422 | x = *it; 423 | if (++it == ch.end()) break; 424 | for (i = 0; i < CHUNKSIZE; i++, x /= RADIX) 425 | ret += DIGITS[x%RADIX]; 426 | } 427 | for (; x; x /= RADIX) ret += DIGITS[x%RADIX]; 428 | if (neg) ret += '-'; 429 | reverse(ret.begin(), ret.end()); 430 | return ret; 431 | } 432 | friend inline ostream& operator<<(ostream& o, const BigInt& b) 433 | {return o << b.tostring();} 434 | friend inline istream& operator>>(istream& i, BigInt& b) 435 | {string s; i >> s; b = BigInt(s); return i;} 436 | inline void trim() { 437 | while (ch.size() && !ch.back()) ch.pop_back(); 438 | if (zero()) neg = false; 439 | } 440 | 441 | inline BigInt() {neg = false;} 442 | inline BigInt(const BigInt& b) {ch = b.ch; neg = b.neg;} 443 | template 444 | BigInt(const BigInt& b) { 445 | if (b.zero()) {*this = BigInt(); return;} 446 | neg = false; 447 | BigInt p(1); 448 | for (int i = 0; i < b.ch.size(); i++) { 449 | *this += p*b.ch[i]; 450 | p *= CR; 451 | } 452 | neg = b.neg; 453 | } 454 | BigInt(int64 n) { 455 | if ((neg = (n < 0))) n = -n; 456 | for (; n; n /= CHUNKRADIX) ch.push_back(n%CHUNKRADIX); 457 | } 458 | inline BigInt(int n) {*this = BigInt((int64)n);} 459 | BigInt(const char *s) { 460 | const char *it, *it2 = s-1; 461 | if ((neg = (*s=='-'))) it2++; 462 | int x = 0, y = 1, z; 463 | for (it = s; *it; it++); 464 | for (--it; it != it2; --it) { 465 | z = DIGITS.find(toupper(*it)); 466 | if (z < 0 || z >= RADIX) {ch.clear(); x = 0; y = 1; continue;} 467 | x += y*z; y *= RADIX; 468 | if (y == CHUNKRADIX) {ch.push_back(x); x = 0; y = 1;} 469 | } 470 | if (y > 1) ch.push_back(x); 471 | trim(); 472 | } 473 | inline BigInt(const string& s) {*this = BigInt(s.c_str());} 474 | }; 475 | 476 | typedef BigInt<10, 1000000000, 9, int> bigint; 477 | typedef BigInt<2, (1LL<<30), 30, unsigned> binarybigint; 478 | typedef BigInt<16, (1<<28), 7, int> hexbigint; 479 | 480 | #endif // __MATHTYPES_H 481 | -------------------------------------------------------------------------------- /matrix.h: -------------------------------------------------------------------------------- 1 | #ifndef __MATRIX_H 2 | #define __MATRIX_H 3 | 4 | //// Matrix manipulation and linear algebra. Formatted for process.exe. 5 | 6 | template vector > MatrixAdd(const vector > &a, const vector > &b) { 7 | if (!a.size() || a.size() != b.size() || a[0].size() != b[0].size()) { 8 | return vector >(); // ERROR 9 | } 10 | vector > ret(a.size(), vector(a[0].size())); 11 | for (int i = 0; i < ret.size(); i++) 12 | for (int j = 0; j < ret[0].size(); j++) 13 | ret[i][j] = a[i][j] + b[i][j]; 14 | return ret; 15 | } 16 | 17 | template vector > MatrixMult(const vector > &a, const vector > &b) { 18 | if (!a.size() || !b.size() || a[0].size() != b.size()) { 19 | return vector >(); // ERROR 20 | } 21 | vector > ret(a.size(), vector(b[0].size())); 22 | for (int i = 0; i < ret.size(); i++) 23 | for (int j = 0; j < ret[0].size(); j++) 24 | for (int k = 0; k < a[0].size(); k++) 25 | ret[i][j] += a[i][k] * b[k][j]; 26 | return ret; 27 | } 28 | 29 | template vector > MatrixPow(vector > a, int pow) { 30 | if (!a.size() || a.size() != a[0].size()) { 31 | return vector >(); // ERROR 32 | } 33 | vector > ret(a.size(), vector(a[0].size())); 34 | for (int i = 0; i < ret.size(); i++) ret[i][i] = 1; 35 | for(;;) { 36 | if (pow&1) ret = MatrixMult(ret, a); 37 | if (!(pow>>=1)) return ret; 38 | a = MatrixMult(a, a); 39 | } 40 | return ret; 41 | } 42 | 43 | template vector > MatrixRotateCL(const vector > &a) { 44 | if (!a.size()) return a; 45 | vector > ret(a[0].size(), vector(a.size())); 46 | for (int i = 0; i < a.size(); i++) 47 | for (int j = 0; j < a[0].size(); j++) 48 | ret[j][a.size()-1-i] = a[i][j]; 49 | return ret; 50 | } 51 | 52 | template vector > MatrixRotateCCL(const vector > &a) { 53 | if (!a.size()) return a; 54 | vector > ret(a[0].size(), vector(a.size())); 55 | for (int i = 0; i < a.size(); i++) 56 | for (int j = 0; j < a[0].size(); j++) 57 | ret[i][j] = a[j][a.size()-1-i]; 58 | return ret; 59 | } 60 | 61 | template vector > MatrixTranspose(const vector > &a) { 62 | if (!a.size()) return a; 63 | vector > ret(a[0].size(), vector(a.size())); 64 | for (int i = 0; i < a.size(); i++) 65 | for (int j = 0; j < a[0].size(); j++) 66 | ret[j][i] = a[i][j]; 67 | return ret; 68 | } 69 | 70 | template vector > MatrixRotate180(vector > a) { 71 | reverse(a.begin(), a.end()); 72 | for (int i = 0; i < a.size(); i++) reverse(a[i].begin(), a[i].end()); 73 | return a; 74 | } 75 | 76 | template vector > MatrixFlipHorizontal(vector > a) { 77 | for (int i = 0; i < a.size(); i++) reverse(a[i].begin(), a[i].end()); 78 | return a; 79 | } 80 | 81 | template vector > MatrixFlipVertical(vector > a) { 82 | reverse(a.begin(), a.end()); 83 | return a; 84 | } 85 | 86 | template vector > MatrixPad(const vector >& a, T pad) { 87 | vector > ret(a.size()+2, vector(a[0].size()+2, pad)); 88 | for (int i = 0; i < a.size(); i++) 89 | for (int j = 0; j < a[0].size(); j++) 90 | ret[i+1][j+1] = a[i][j]; 91 | return ret; 92 | } 93 | 94 | #endif // __MATRIX_H 95 | -------------------------------------------------------------------------------- /misc.h: -------------------------------------------------------------------------------- 1 | #ifndef __MISC_H 2 | #define __MISC_H 3 | 4 | //// Miscellaneous functions that sometimes come in handy in contests. 5 | //// Formatted for process.exe. 6 | 7 | //// *** Calendar *** 8 | 9 | int IsLeapYear(int y) {return y%4 == 0 && (y%100 || y%400 == 0);} 10 | 11 | int DaysSince1600(int d, int m, int y) { 12 | // Returns # of days since Jan. 1, 1600 (ie, 1 1 1600 returns 0). 13 | static int md[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; 14 | return d-1 + md[m-1] + (y-1600)*365 + (y-(m<3)-1596)/4 - (y-(m<3)-1500)/100*3/4; 15 | } 16 | 17 | int DayOfWeek(int d, int m, int y) { 18 | // 0 = Monday, 6 = Sunday 19 | return (DaysSince1600(d, m, y)+5)%7; 20 | } 21 | 22 | //// *** Playing cards *** 23 | 24 | #define CARD_RANKS "23456789TJQKA" 25 | #define CARD_SUITS "CDHS" 26 | 27 | inline int CardToInt(char rank, char suit) { 28 | const char* r = strchr(CARD_RANKS, rank); 29 | const char* s = strchr(CARD_SUITS, suit); 30 | if (!r || !s) return -1; 31 | return (r-CARD_RANKS)*4 + (s-CARD_SUITS); 32 | } 33 | 34 | // Takes in a set of 5 cards and turns them into an integer ranking the poker 35 | // hand. Takes high cards, etc., into account. Take the top byte if you just 36 | // want the hand's description. 37 | enum {HIGH_CARD, ONE_PAIR, TWO_PAIRS, THREE_OF_A_KIND, STRAIGHT, FLUSH, 38 | FULL_HOUSE, FOUR_OF_A_KIND, STRAIGHT_FLUSH, ROYAL_FLUSH}; 39 | int PokerHand(const vector& hand) { 40 | bool flush = true; 41 | for (int i = 0; i+1 < 5; i++) { 42 | if ((hand[i]&3) != (hand[i+1]&3)) flush = false; 43 | } 44 | 45 | vector > rank; 46 | for (int i = 0, j; i < 5; i++) { 47 | int r = hand[i]>>2; 48 | for (j = 0; j < rank.size(); j++) if (rank[j].second == r) break; 49 | if (j == rank.size()) { 50 | rank.push_back(make_pair(1, r)); 51 | } else { 52 | rank[j].first++; 53 | } 54 | } 55 | sort(rank.begin(), rank.end()); 56 | 57 | int all_ranks = 0; 58 | for (int i = rank.size()-1; i >= 0; i--) { 59 | all_ranks = (all_ranks<<4) + rank[i].second; 60 | } 61 | 62 | int straight = -1; 63 | if (rank.back().first == 1 && rank[4].second-rank[0].second == 4) { 64 | straight = rank[4].second; 65 | } 66 | // Special case for low straights. 67 | if (rank.back().first == 1 && rank[4].second == 12 && rank[3].second == 3) { 68 | straight = rank[3].second; 69 | } 70 | 71 | if (flush && straight == 12) { 72 | return (ROYAL_FLUSH<<24); 73 | } 74 | if (flush && straight != -1) { 75 | return (STRAIGHT_FLUSH<<24) + straight; 76 | } 77 | if (rank.back().first == 4) { 78 | return (FOUR_OF_A_KIND<<24) + all_ranks; 79 | } 80 | if (rank.back().first == 3 && rank[0].first == 2) { 81 | return (FULL_HOUSE<<24) + all_ranks; 82 | } 83 | if (flush) { 84 | return (FLUSH<<24) + all_ranks; 85 | } 86 | if (straight != -1) { 87 | return (STRAIGHT<<24) + straight; 88 | } 89 | if (rank.back().first == 3) { 90 | return (THREE_OF_A_KIND<<24) + all_ranks; 91 | } 92 | if (rank.back().first == 2 && rank[1].first == 2) { 93 | return (TWO_PAIRS<<24) + all_ranks; 94 | } 95 | if (rank.back().first == 2) { 96 | return (ONE_PAIR<<24) + all_ranks; 97 | } 98 | return (HIGH_CARD<<24) + all_ranks; 99 | } 100 | 101 | //// *** Potpourri *** 102 | 103 | string RomanNumeral(int x) { 104 | static string s[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; 105 | static int val[] ={1000,900, 500,400, 100,90, 50, 40, 10, 9, 5, 4, 1 }; 106 | string ret; 107 | for (int i = 0; x; i++) 108 | while (x >= val[i]) {x -= val[i]; ret += s[i];} 109 | return ret; 110 | } 111 | 112 | 113 | int64 Rand64() { 114 | // Note that the upper bits of rand() are more reliably random. 115 | return ((int64)rand()<<33) ^ ((int64)rand()<<11) ^ ((int64)rand()>>9); 116 | } 117 | 118 | #endif // __MISC_H 119 | -------------------------------------------------------------------------------- /old/avl.cc: -------------------------------------------------------------------------------- 1 | template 2 | class AVLNode { 3 | inline void check() { 4 | height = max(lc->height, rc->height)+1; 5 | lc->par = rc->par = this; 6 | } 7 | void rotateLeft() { 8 | AVLNode *u = rc; 9 | rc = u->rc; u->rc = u->lc; u->lc = lc; lc = u; 10 | swap(key, u->key); u->check(); check(); 11 | } 12 | void rotateRight() { 13 | AVLNode *u = lc; 14 | lc = u->lc; u->lc = u->rc; u->rc = rc; rc = u; 15 | swap(key, u->key); u->check(); check(); 16 | } 17 | void balance() { 18 | check(); 19 | if( lc->height == rc->height+2 ) { 20 | if( lc->lc->height >= lc->rc->height ) 21 | rotateRight(); 22 | else 23 | {lc->rotateLeft(); rotateRight();} 24 | } else if( rc->height == lc->height+2 ) { 25 | if( rc->rc->height >= rc->lc->height ) 26 | rotateLeft(); 27 | else 28 | {rc->rotateRight(); rotateLeft();} 29 | } 30 | } 31 | 32 | public: 33 | T key; 34 | signed char height; 35 | AVLNode *lc, *rc, *par; 36 | 37 | struct iterator { 38 | AVLNode *p; 39 | inline iterator(AVLNode *pt = 0) : p(pt) {} 40 | inline operator AVLNode *() {return p;} 41 | iterator &operator++() { 42 | if( p->rc->height != -1 ) return *this = p->rc->begin(); 43 | while( p->par && p->par->rc == p ) p = p->par; 44 | return *this = p->par; 45 | } 46 | iterator operator++(int) {iterator tmp = *this; ++*this; return tmp;} 47 | }; 48 | iterator begin() { 49 | if( height == -1 ) return 0; 50 | return (lc->height == -1) ? iterator(this) : lc->begin(); 51 | } 52 | iterator end() {return 0;} 53 | 54 | AVLNode *find(const T &k) const { 55 | if( height == -1 ) return 0; 56 | if( key == k ) return this; 57 | return ((key>k)?lc:rc)->find(k); 58 | } 59 | void insert(const T &k) { 60 | if( height == -1 ) { 61 | key = k; lc = new AVLNode(); rc = new AVLNode(); check(); 62 | for( AVLNode *u = par; u; u = u->par ) u->balance(); 63 | } else if( multi || key != k ) 64 | ((key>k)?lc:rc)->insert(k); 65 | } 66 | void remove(const T &k) { 67 | if( height == -1 ) return; 68 | if( key == k ) { 69 | if( height == 0 ) { 70 | delete lc; delete rc; lc = rc = 0; height = -1; 71 | for( AVLNode *u = par; u; u = u->par ) u->balance(); 72 | } else { 73 | AVLNode *u; 74 | if( lc->height > rc->height ) 75 | for( u = lc; u->rc->height != -1; u = u->rc ); 76 | else 77 | for( u = rc; u->lc->height != -1; u = u->lc ); 78 | swap(key, u->key); u->remove(u->key); 79 | } 80 | } else 81 | ((key>k)?lc:rc)->remove(k); 82 | } 83 | ~AVLNode() {if( lc ) delete lc; if( rc ) delete rc;} 84 | AVLNode() {height = -1; lc = rc = par = 0;} 85 | }; 86 | -------------------------------------------------------------------------------- /old/bfspqtemp.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #define S1 20 3 | #define S2 20 4 | #define S3 1000 5 | vector best; 6 | vector prev; 7 | priority_queue > q; 8 | 9 | inline int enc(int v1, int v2, int v3) { 10 | return ((v1)*S2+v2)*S3+v3; 11 | } 12 | 13 | inline int dec(const int &v, int &v1, int &v2, int &v3) { 14 | v1 = v/S3/S2; 15 | v2 = v/S3%S2; 16 | v3 = v%S3; 17 | } 18 | 19 | inline void move(int p, int v1, int v2, int v3, int d) { 20 | if( v1 < 0 || v1 >= S1 ) return; 21 | if( v2 < 0 || v2 >= S2 ) return; 22 | if( v3 < 0 || v3 >= S3 ) return; 23 | int v = enc(v1, v2, v3); 24 | if( best[v] != -1 && best[v] <= d ) return; 25 | // check other state validity here 26 | best[v] = d; 27 | prev[v] = p; 28 | q.push(pair(-d, v)); 29 | } 30 | 31 | int dobfs(int s, int e) { 32 | int d, v, v1, v2, v3; 33 | best = prev = vector(S1*S2*S3, -1); 34 | q = priority_queue >(); 35 | q.push(pair(0, s)); 36 | best[s] = 0; 37 | while( !q.empty() && q.top().second != e ) { 38 | d = -q.top().first; v = q.top().second; q.pop(); 39 | dec(v, v1, v2, v3); 40 | //add moves here, ie move(v, v1-1, v2, v3, d+3); 41 | } 42 | return best[e]; 43 | } 44 | -------------------------------------------------------------------------------- /old/bfstemp.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #define S1 20 3 | #define S2 20 4 | #define S3 1000 5 | vector best; 6 | vector prev; 7 | queue q; 8 | 9 | inline int enc(int v1, int v2, int v3) { 10 | return ((v1)*S2+v2)*S3+v3; 11 | } 12 | 13 | inline int dec(const int &v, int &v1, int &v2, int &v3) { 14 | v1 = v/S3/S2; 15 | v2 = v/S3%S2; 16 | v3 = v%S3; 17 | } 18 | 19 | inline void move(int p, int v1, int v2, int v3) { 20 | if( v1 < 0 || v1 >= S1 ) return; 21 | if( v2 < 0 || v2 >= S2 ) return; 22 | if( v3 < 0 || v3 >= S3 ) return; 23 | int v = enc(v1, v2, v3); 24 | if( best[v] != -1 ) return; 25 | // check other state validity here 26 | best[v] = best[p]+1; 27 | prev[v] = p; 28 | q.push(v); 29 | } 30 | 31 | int dobfs(int s, int e) { 32 | int v, v1, v2, v3; 33 | best = prev = vector(S1*S2*S3, -1); 34 | q = queue(); 35 | q.push(s); 36 | best[s] = 0; 37 | while( !q.empty() && best[e] == -1 ) { 38 | v = q.front(); q.pop(); 39 | dec(v, v1, v2, v3); 40 | //add moves here, ie move(v, v1-1, v2, v3); 41 | } 42 | return best[e]; 43 | } 44 | -------------------------------------------------------------------------------- /old/bigint.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) Derek Kisman (SnapDragon) dkisman@gmail.com 2 | // You must ask permission to use my BigInt code in your contests 3 | const string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 4 | typedef long long i64; 5 | 6 | template 7 | class BigInt { 8 | public: 9 | vector ch; 10 | bool neg; 11 | 12 | BigInt &operator+=(const BigInt &b) { 13 | int car = 0; unsigned x; 14 | for (int i = 0; i < ch.size() || i < b.ch.size(); i++) { 15 | x = CHUNKRADIX + car + ((i zeros; 40 | for (auto it = b.ch.begin(); it != b.ch.end(); it++) { 41 | BigInt b3 = b2 * *it; 42 | b3.ch.insert(b3.ch.begin(), zeros.begin(), zeros.end()); 43 | *this += b3; 44 | zeros.push_back(0); 45 | } 46 | if (b.neg && !zero()) neg = !neg; 47 | return *this; 48 | } 49 | inline BigInt operator*(const BigInt &b) const {return BigInt(*this)*=b;} 50 | BigInt &operator/=(BigInt b) { 51 | bool retneg = (b.neg) ? !neg : neg; 52 | b.neg = neg = false; 53 | if (b > *this || b.zero()) return (*this=BigInt()); 54 | if (b.ch.size() == 1) return (*this /= retneg ? -b.ch[0] : b.ch[0]); 55 | if (CHUNKRADIX >= (1<<21)) { 56 | int bm = CHUNKRADIX/b.ch.back() + 1; b *= bm; *this *= bm; 57 | } 58 | i64 p, q = (i64)CHUNKRADIX*b.ch.back() + b.ch[b.ch.size()-2]; 59 | vector ret(ch.size()-b.ch.size()+1); 60 | b.ch.insert(b.ch.begin(), ret.begin(), ret.end()); 61 | for (int i = ret.size()-1, j = ch.size()-1; i >= 0; i--, j--) { 62 | b.ch.erase(b.ch.begin()); 63 | if (j >= ch.size()) {ret[i] = 0; continue;} 64 | p = (i64)CHUNKRADIX*ch[j] + ch[j-1] + 1; 65 | if (j+1 < ch.size()) p += (i64)CHUNKRADIX*CHUNKRADIX*ch[j+1]; 66 | *this -= b*(ret[i] = p/q); 67 | while (neg) {*this += b; ret[i]--;} 68 | } 69 | ch = ret; neg = retneg; 70 | trim(); 71 | return *this; 72 | } 73 | inline BigInt operator/(const BigInt &b) const {return BigInt(*this)/=b;} 74 | inline BigInt &operator%=(const BigInt &b) {return *this -= (*this/b)*b;} 75 | inline BigInt operator%(const BigInt &b) const {return BigInt(*this)%=b;} 76 | BigInt &operator*=(int x) { 77 | if (!x || zero()) return (*this = BigInt()); 78 | neg ^= (x<0); 79 | i64 car = 0, xl = abs(x); if (xl == 1) return *this; 80 | for (auto it = ch.begin(); it != ch.end(); it++) { 81 | car += *it * xl; 82 | *it = car%CHUNKRADIX; 83 | car /= CHUNKRADIX; 84 | } 85 | while (car) {ch.push_back(car%CHUNKRADIX); car /= CHUNKRADIX;} 86 | return *this; 87 | } 88 | inline BigInt operator*(int x) const {return BigInt(*this)*=x;} 89 | BigInt &operator/=(int x) { 90 | if (!x) {return *this = BigInt();} 91 | neg ^= (x<0); 92 | i64 car = 0; x = abs(x); if (x == 1) return *this; 93 | for (auto it = ch.rbegin(); it != ch.rend(); it++) { 94 | car = CHUNKRADIX*car + *it; 95 | *it = car / x; 96 | car %= x; 97 | } 98 | trim(); 99 | return *this; 100 | } 101 | inline BigInt operator/(int x) const {return BigInt(*this)/=x;} 102 | int operator%(int x) const { 103 | int ret = 0; x = abs(x); 104 | auto it = ch.rbegin(); 105 | if (CHUNKRADIX%x == 0 && ch.size()) {it = --ch.rend();} 106 | for (; it != ch.rend(); it++) ret = ((i64)CHUNKRADIX*ret + *it)%x; 107 | return neg ? -ret : ret; 108 | } 109 | 110 | bool operator<(const BigInt &b) const { 111 | if (neg != b.neg) return neg; 112 | if (ch.size() != b.ch.size()) return neg ^ (ch.size() < b.ch.size()); 113 | for (int i = ch.size()-1; i >= 0; i--) 114 | if (ch[i] != b.ch[i]) return neg ^ (ch[i] < b.ch[i]); 115 | return false; 116 | } 117 | bool operator<=(const BigInt &b) const { 118 | if (neg != b.neg) return neg; 119 | if (ch.size() != b.ch.size()) return neg ^ (ch.size() < b.ch.size()); 120 | for (int i = ch.size()-1; i >= 0; i--) 121 | if (ch[i] != b.ch[i]) return neg ^ (ch[i] < b.ch[i]); 122 | return true; 123 | } 124 | inline bool operator==(const BigInt &b) const 125 | {return neg==b.neg && ch==b.ch;} 126 | inline bool operator>(const BigInt &b) const {return !(*this <= b);} 127 | inline bool operator>=(const BigInt &b) const {return !(*this < b);} 128 | inline bool operator!=(const BigInt &b) const {return !(*this == b);} 129 | friend inline BigInt operator-(const BigInt &b) 130 | {BigInt ret(b); ret.neg = !ret.neg; return ret;} 131 | friend inline BigInt abs(const BigInt &b) {return b.neg ? -b : b;} 132 | 133 | size_t digits() const { 134 | if (ch.size() == 0) return 1; 135 | size_t ret = (ch.size()-1)*CHUNKSIZE; 136 | for (int x = ch.back(); x; x /= RADIX) ret++; 137 | return ret; 138 | } 139 | inline bool zero() const {return ch.size() == 0;} 140 | i64 toint() const { 141 | i64 ret = 0; 142 | for (auto it = ch.rbegin(); it != ch.rend(); it++) 143 | ret = ret*CHUNKRADIX + *it; 144 | return neg ? -ret : ret; 145 | } 146 | string tostring() const { 147 | if (ch.size() == 0) return "0"; 148 | auto it = ch.begin(); 149 | string ret; 150 | int i, x; 151 | while (it != ch.end()) { 152 | x = *it; 153 | if (++it == ch.end()) break; 154 | for (i = 0; i < CHUNKSIZE; i++, x /= RADIX) 155 | ret += DIGITS[x%RADIX]; 156 | } 157 | for (; x; x /= RADIX) ret += DIGITS[x%RADIX]; 158 | if (neg) ret += '-'; 159 | reverse(ret.begin(), ret.end()); 160 | return ret; 161 | } 162 | friend inline ostream &operator<<(ostream &o, const BigInt &b) 163 | {return o << b.tostring();} 164 | friend inline istream &operator>>(istream &i, BigInt &b) 165 | {string s; i >> s; b = BigInt(s); return i;} 166 | inline void trim() { 167 | while (ch.size() && !ch.back()) ch.pop_back(); 168 | if (zero()) neg = false; 169 | } 170 | 171 | inline BigInt() {neg = false;} 172 | inline BigInt(const BigInt &b) {ch = b.ch; neg = b.neg;} 173 | template 174 | BigInt(const BigInt &b) { 175 | if (b.zero()) {*this = BigInt(); return;} 176 | neg = false; 177 | BigInt p(1); 178 | for (int i = 0; i < b.ch.size(); i++) { 179 | *this += p*b.ch[i]; 180 | p *= CR; 181 | } 182 | neg = b.neg; 183 | } 184 | BigInt(i64 n) { 185 | if ((neg = (n < 0))) n = -n; 186 | for (; n; n /= CHUNKRADIX) ch.push_back(n%CHUNKRADIX); 187 | } 188 | inline BigInt(int n) {*this = BigInt((i64)n);} 189 | BigInt(const char *s) { 190 | const char *it, *it2 = s-1; 191 | if ((neg = (*s=='-'))) it2++; 192 | int x = 0, y = 1, z; 193 | for (it = s; *it; it++); 194 | for (--it; it != it2; --it) { 195 | z = DIGITS.find(toupper(*it)); 196 | if (z < 0 || z >= RADIX) {ch.clear(); x = 0; y = 1; continue;} 197 | x += y*z; y *= RADIX; 198 | if (y == CHUNKRADIX) {ch.push_back(x); x = 0; y = 1;} 199 | } 200 | if (y > 1) ch.push_back(x); 201 | trim(); 202 | } 203 | inline BigInt(const string &s) {*this = BigInt(s.c_str());} 204 | }; 205 | typedef BigInt<10, 1000000000, 9, int> bigint; 206 | typedef BigInt<2, (1<<30), 30, int> binaryint; 207 | typedef BigInt<16, (1<<28), 7, int> hexint; 208 | -------------------------------------------------------------------------------- /old/bigint2.cc: -------------------------------------------------------------------------------- 1 | #define BASE 10 2 | 3 | class bigint { 4 | public: 5 | vector dig; 6 | 7 | bigint operator+(const bigint &b) const { 8 | char car = 0; 9 | vector res; 10 | int i; 11 | for( i = 0; i < size() || i < b.size(); i++ ) { 12 | if( i < size() ) car += dig[i]; 13 | if( i < b.size() ) car += b.dig[i]; 14 | res.push_back( car%BASE ); 15 | car /= BASE; 16 | } 17 | if( car ) res.push_back(car); 18 | return bigint(res); 19 | } 20 | bigint operator-(const bigint &b) const { 21 | char car = BASE; 22 | vector res; 23 | int i; 24 | for( i = 0; i < size(); i++ ) { 25 | car += dig[i]; 26 | if( i < b.size() ) car -= b.dig[i]; 27 | res.push_back( car%BASE ); 28 | car = (car/BASE)+BASE-1; 29 | } 30 | if( car < BASE || i < b.size() ) return bigint(); 31 | while( res.size() > 1 && res.back() == 0 ) res.pop_back(); 32 | return bigint(res); 33 | } 34 | bigint operator*(const bigint &b) const { 35 | if( b.zero() ) return bigint(); 36 | bigint res, term; 37 | vector dp(BASE); 38 | int i; 39 | for( i = 1; i < BASE; i++ ) dp[i] = dp[i-1] + b; 40 | for( i = 0; i < size(); i++ ) { 41 | if( !dig[i] ) continue; 42 | bigint &p = dp[dig[i]]; 43 | term.dig = vector(i); 44 | term.dig.insert(term.dig.end(), p.dig.begin(), p.dig.end()); 45 | res = res + term; 46 | } 47 | return res; 48 | } 49 | bigint operator/(const bigint &b) const { 50 | if( b.zero() || b > *this ) return bigint(); 51 | bigint cur = *this, term; 52 | vector res; 53 | vector dp(BASE); 54 | int i; 55 | char d; 56 | for( i = 1; i < BASE; i++ ) dp[i] = dp[i-1] + b; 57 | for( i = size()-b.size(); i >= 0; i-- ) { 58 | for( d = BASE-1; d > 0; d-- ) { 59 | bigint &p = dp[d]; 60 | term.dig = vector(i); 61 | term.dig.insert(term.dig.end(), p.dig.begin(), p.dig.end()); 62 | if( term <= cur ) break; 63 | } 64 | res.push_back(d); 65 | if( d ) cur = cur - term; 66 | } 67 | reverse( res.begin(), res.end() ); 68 | while( res.back() == 0 ) res.pop_back(); 69 | return bigint(res); 70 | } 71 | bigint operator%(const bigint &b) const { 72 | return *this - (*this / b) * b; 73 | } 74 | bool operator<(const bigint &b) const { 75 | if( size() != b.size() ) return( size() < b.size() ); 76 | for( int i = size()-1; i >= 0; i-- ) 77 | if( dig[i] != b.dig[i] ) return( dig[i] < b.dig[i] ); 78 | return false; 79 | } 80 | bool operator<=(const bigint &b) const { 81 | if( size() != b.size() ) return( size() < b.size() ); 82 | for( int i = size()-1; i >= 0; i-- ) 83 | if( dig[i] != b.dig[i] ) return( dig[i] < b.dig[i] ); 84 | return true; 85 | } 86 | bool operator>(const bigint &b) const {return !(*this <= b);} 87 | bool operator>=(const bigint &b) const {return !(*this < b);} 88 | 89 | inline size_t size() const {return dig.size();} 90 | inline bool zero() const {return (dig.size() == 1 && dig[0] == 0);} 91 | u64 toint() const { 92 | u64 ret = 0; 93 | for( int i = size()-1; i >= 0; i-- ) 94 | ret = ret*10 + dig[i]; 95 | } 96 | string tostring() const { 97 | vector::const_reverse_iterator it; 98 | string ret; 99 | for( it = dig.rbegin(); it != dig.rend(); it++ ) 100 | ret += *it+'0'; 101 | return ret; 102 | } 103 | 104 | bigint() {dig.push_back(0);} 105 | bigint( const vector &vc ) {dig = vc;} 106 | bigint( u64 n ) { 107 | if( !n ) dig.push_back(0); 108 | while( n > 0 ) { 109 | dig.push_back(n%BASE); 110 | n /= BASE; 111 | } 112 | } 113 | bigint( const string &s ) { 114 | string::const_reverse_iterator it; 115 | for( it = s.rbegin(); it != s.rend(); it++ ) 116 | dig.push_back(*it-'0'); 117 | } 118 | }; 119 | -------------------------------------------------------------------------------- /old/conway.cc: -------------------------------------------------------------------------------- 1 | #define MAX_GAMES 1000 2 | 3 | class ConwayGame { 4 | private: 5 | ConwayGame() {} // Private; only MakeConwayGame should construct games. 6 | struct ConwayGameHash { 7 | int operator()(const ConwayGame* G) const { 8 | return G->hash; 9 | } 10 | }; 11 | struct ConwayGameEq { 12 | bool operator()(const ConwayGame* G, const ConwayGame* H) const { 13 | return *G == *H; 14 | } 15 | }; 16 | 17 | public: 18 | int index; // Index of this game into list of canonical games. 19 | int hash; // G == H implies G.hash == H.hash. 20 | vector L, R; 21 | 22 | static const ConwayGame& MakeConwayGame(const vector& l, 23 | const vector& r) { 24 | static hash_set 25 | canonical_games; 26 | 27 | // Canonicalize the game. 28 | ConwayGame* G = new ConwayGame(); 29 | G->L = l; G->R = r; G->index = canonical_games.size(); 30 | G->RemoveDominatedOptions(); 31 | while (G->ReplaceReversibleMoves()) G->RemoveDominatedOptions(); 32 | 33 | int lhash = 392384382, rhash = -1495686783; 34 | for (int i = 0; i < G->L.size(); i++) lhash += G->L[i]->hash; 35 | for (int i = 0; i < G->R.size(); i++) rhash += G->R[i]->hash; 36 | G->hash = (lhash ^ rhash); 37 | 38 | pair response = 39 | canonical_games.insert(G); 40 | if (response.second) { 41 | // This is a new game. 42 | if (canonical_games.size() > MAX_GAMES) { 43 | cerr << "Too many games in memory!"; 44 | exit(0); 45 | } 46 | return *G; 47 | } else { 48 | // This was a known game. Clear leq_memo in a fast way. 49 | if ((leq_cookie[G->index] += 2) < 0) { 50 | leq_cookie[G->index] = 0; 51 | for (int i = 0; i <= G->index; i++) 52 | leq_memo[G->index][i] = leq_memo[i][G->index] = 0; 53 | } 54 | delete G; 55 | return **response.first; 56 | } 57 | } 58 | 59 | bool RemoveDominatedOptions() { 60 | bool changed = false; 61 | for (int i = 0; i < L.size(); i++) 62 | for (int j = 0; j < L.size(); j++) 63 | if (j != i && *L[j] <= *L[i]) { 64 | L.erase(L.begin() + j); 65 | if (i > j--) i--; 66 | changed = true; 67 | } 68 | for (int i = 0; i < R.size(); i++) 69 | for (int j = 0; j < R.size(); j++) 70 | if (j != i && *R[i] <= *R[j]) { 71 | R.erase(R.begin() + j); 72 | if (i > j--) i--; 73 | changed = true; 74 | } 75 | return changed; 76 | } 77 | 78 | bool ReplaceReversibleMoves() { 79 | bool changed = false; 80 | for (int i = 0; i < L.size(); i++) 81 | for (int j = 0; j < L[i]->R.size(); j++) { 82 | const ConwayGame& G = *L[i]->R[j]; 83 | if (G <= *this) { 84 | L.erase(L.begin() + i--); 85 | L.insert(L.end(), G.L.begin(), G.L.end()); 86 | changed = true; 87 | break; 88 | } 89 | } 90 | for (int i = 0; i < R.size(); i++) 91 | for (int j = 0; j < R[i]->L.size(); j++) { 92 | const ConwayGame& G = *R[i]->L[j]; 93 | if (*this <= G) { 94 | R.erase(R.begin() + i--); 95 | R.insert(R.end(), G.R.begin(), G.R.end()); 96 | changed = true; 97 | break; 98 | } 99 | } 100 | return changed; 101 | } 102 | 103 | static const ConwayGame& ZERO; 104 | static const ConwayGame& ONE; 105 | static const ConwayGame& STAR; 106 | static const ConwayGame& ConwayInteger(int v) { 107 | if (v == 0) { 108 | return ZERO; 109 | } else if (v > 0) { 110 | return ConwayInteger(v-1) + ONE; 111 | } else { 112 | return ConwayInteger(v+1) - ONE; 113 | } 114 | } 115 | 116 | static int leq_memo[MAX_GAMES][MAX_GAMES]; 117 | static int leq_cookie[MAX_GAMES]; 118 | bool operator<=(const ConwayGame& G) const { 119 | int& ret = leq_memo[index][G.index]; 120 | int cookie = leq_cookie[max(index, G.index)]; 121 | if (ret > cookie) return ret & 1; 122 | for (int i = 0; i < L.size(); i++) 123 | if (G <= *L[i]) {ret = cookie+2; return false;} 124 | for (int i = 0; i < G.R.size(); i++) 125 | if (*G.R[i] <= *this) {ret = cookie+2; return false;} 126 | ret = cookie+1; return true; 127 | } 128 | bool operator<(const ConwayGame& G) const {return *this<=G && !(G<=*this);} 129 | bool operator>=(const ConwayGame& G) const {return G <= *this;} 130 | bool operator>(const ConwayGame& G) const {return G<=*this && !(*this<=G);} 131 | bool operator==(const ConwayGame& G) const {return G<=*this && *this<=G;} 132 | bool operator!=(const ConwayGame& G) const {return !(G == *this);} 133 | bool Fuzzy(const ConwayGame &G) {return !(*this <= G) && !(G <= *this);} 134 | 135 | const ConwayGame& operator-() const { 136 | static const ConwayGame* neg_memo[MAX_GAMES]; 137 | const ConwayGame*& ret = neg_memo[index]; 138 | if (ret) return *ret; 139 | vector l, r; 140 | for (int i = 0; i < L.size(); i++) r.push_back(&(-*L[i])); 141 | for (int i = 0; i < R.size(); i++) l.push_back(&(-*R[i])); 142 | return *(ret = &MakeConwayGame(l, r)); 143 | } 144 | 145 | const ConwayGame& operator+(const ConwayGame& G) const { 146 | static const ConwayGame* add_memo[MAX_GAMES][MAX_GAMES]; 147 | const ConwayGame*& ret = add_memo[index][G.index]; 148 | if (ret) return *ret; 149 | vector l, r; 150 | for (int i = 0; i < L.size(); i++) l.push_back(&(*L[i] + G)); 151 | for (int i = 0; i < G.L.size(); i++) l.push_back(&(*this + *G.L[i])); 152 | for (int i = 0; i < R.size(); i++) r.push_back(&(*R[i] + G)); 153 | for (int i = 0; i < G.R.size(); i++) r.push_back(&(*this + *G.R[i])); 154 | add_memo[G.index][index] = ret = &MakeConwayGame(l, r); 155 | return *ret; 156 | } 157 | ConwayGame& operator+=(const ConwayGame& G) {return *this = *this + G;} 158 | const ConwayGame& operator-(const ConwayGame& G) const {return *this + -G;} 159 | ConwayGame& operator-=(const ConwayGame& G) {return *this = *this + -G;} 160 | 161 | string Representation() const { 162 | string ret = "{"; 163 | for (int i = 0; i < L.size(); i++) { 164 | if (i) ret += ','; 165 | ret += L[i]->Representation(); 166 | } 167 | ret += '|'; 168 | for (int i = 0; i < R.size(); i++) { 169 | if (i) ret += ','; 170 | ret += R[i]->Representation(); 171 | } 172 | ret += '}'; 173 | if (ret == "{|}") return "0"; 174 | if (ret == "{0|0}") return "*"; 175 | int v, n; 176 | if (sscanf(ret.c_str(), "{%d|}%n", &v, &n) && n == ret.size()) 177 | return ToString(v+1); 178 | if (sscanf(ret.c_str(), "{|%d}%n", &v, &n) && n == ret.size()) 179 | return ToString(v-1); 180 | return ret; 181 | } 182 | friend ostream& operator<<(ostream& out, ConwayGame G) { 183 | out << G.Representation(); 184 | return out; 185 | } 186 | }; 187 | int ConwayGame::leq_memo[MAX_GAMES][MAX_GAMES]; 188 | int ConwayGame::leq_cookie[MAX_GAMES]; 189 | const ConwayGame& ConwayGame::ZERO = 190 | MakeConwayGame(vector(), 191 | vector()); 192 | const ConwayGame& ConwayGame::ONE = 193 | MakeConwayGame(vector(1, &ConwayGame::ZERO), 194 | vector()); 195 | const ConwayGame& ConwayGame::STAR = 196 | MakeConwayGame(vector(1, &ConwayGame::ZERO), 197 | vector(1, &ConwayGame::ZERO)); 198 | -------------------------------------------------------------------------------- /old/die.cc: -------------------------------------------------------------------------------- 1 | #define TOP 0 2 | #define BOTTOM 1 3 | #define LEFT 2 4 | #define RIGHT 3 5 | #define FRONT 4 6 | #define BACK 5 7 | class Die { 8 | public: 9 | int face[6]; 10 | 11 | // turn one side to another in 1 or 2 rotations 12 | void roll(int startface, int endface) { 13 | if( startface == endface ) return; 14 | if( startface == (endface^1) ) { 15 | swap(face[startface], face[endface]); 16 | swap(face[(startface+2)%6], face[(endface+2)%6]); 17 | } else { 18 | int x = face[endface]; 19 | face[endface] = face[startface]; 20 | face[startface] = face[endface^1]; 21 | face[endface^1] = face[startface^1]; 22 | face[startface^1] = x; 23 | } 24 | } 25 | void mirror() {swap(face[LEFT], face[RIGHT]);} 26 | void orient(int topnum, int frontnum) { 27 | int x; 28 | for( x = 0; x < 6; x++ ) if( face[x] == topnum ) break; 29 | roll(x, TOP); 30 | for( x = 0; x < 6; x++ ) if( face[x] == frontnum ) break; 31 | if( x == BACK ) {roll(LEFT, FRONT); roll(LEFT, FRONT);} 32 | else roll(x, FRONT); 33 | } 34 | void orient(int topnum, int frontnum, int leftnum) { 35 | orient(topnum, frontnum); 36 | if( face[LEFT] != leftnum ) mirror(); 37 | } 38 | Die() {face[0] = 6; face[1] = 1; face[2] = 3; 39 | face[3] = 4; face[4] = 2; face[5] = 5;} 40 | }; 41 | -------------------------------------------------------------------------------- /old/fract.cc: -------------------------------------------------------------------------------- 1 | i64 gcd(i64 a, i64 b) { 2 | i64 n; 3 | a = (a<0)?-a:a; 4 | b = (b<0)?-b:b; 5 | while( b ) { 6 | n = b; 7 | b = a%b; 8 | a = n; 9 | } 10 | return a; 11 | } 12 | 13 | class fract { 14 | public: 15 | i64 numer, denom; 16 | 17 | inline fract operator+(const fract &b) const { 18 | return fract(numer*b.denom + denom*b.numer, denom*b.denom); 19 | }; 20 | inline fract operator-(const fract &b) const { 21 | return fract(numer*b.denom - denom*b.numer, denom*b.denom); 22 | }; 23 | inline fract operator*(const fract &b) const { 24 | return fract(numer*b.numer, denom*b.denom); 25 | }; 26 | inline fract operator/(const fract &b) const { 27 | return fract(numer*b.denom, denom*b.numer); 28 | }; 29 | inline bool operator<(const fract &b) const { 30 | return( numer*b.denom - denom*b.numer < 0 ); 31 | }; 32 | inline bool operator<=(const fract &b) const { 33 | return( numer*b.denom - denom*b.numer <= 0 ); 34 | }; 35 | inline bool operator>(const fract &b) const { 36 | return( numer*b.denom - denom*b.numer > 0 ); 37 | }; 38 | inline bool operator>=(const fract &b) const { 39 | return( numer*b.denom - denom*b.numer > 0 ); 40 | }; 41 | inline bool operator==(const fract &b) const { 42 | return( numer == b.numer && denom == b.denom ); 43 | }; 44 | inline bool operator!=(const fract &b) const { 45 | return( numer != b.numer || denom != b.denom ); 46 | }; 47 | 48 | fract() {numer = 0; denom = 1;} 49 | fract( const i64 &n ) {numer = n; denom = 1;} 50 | fract( const i64 &n, const i64 &d ) { 51 | numer = n; 52 | if( numer == 0 ) {denom = 1; return;} 53 | denom = d; 54 | if( denom < 0 ) {numer = -numer; denom = -denom;} 55 | i64 g = gcd(numer, denom); 56 | numer /= g; 57 | denom /= g; 58 | }; 59 | }; 60 | -------------------------------------------------------------------------------- /old/geom2d.cc: -------------------------------------------------------------------------------- 1 | double INF = (1.0/0.0); 2 | double EPS = 0.0000001; 3 | 4 | struct Vector { 5 | double x, y; 6 | inline Vector operator-(const Vector &v) const { 7 | return Vector(x-v.x, y-v.y); 8 | } 9 | inline Vector operator+(const Vector &v) const { 10 | return Vector(x+v.x, y+v.y); 11 | } 12 | inline bool operator==(const Vector &v) const { 13 | return fabs(x-v.x) < EPS && fabs(y-v.y) < EPS; 14 | } 15 | inline bool operator<(const Vector &v) const { 16 | return x-v.x < -EPS || x-v.x < EPS && y-v.y < -EPS; 17 | } 18 | inline Vector::Vector() {}; 19 | inline Vector::Vector(double x, double y) : x(x), y(y) {}; 20 | }; 21 | typedef Vector Point; 22 | 23 | // NOTE: a Line is "open" (does not contain its vertices) 24 | struct Line { 25 | Point c1, c2; 26 | inline bool operator==(const Line &l) const {return c1==l.c1 && c2==l.c2;} 27 | inline Line::Line() {}; 28 | inline Line::Line(const Point &c1, const Point &c2) : c1(c1), c2(c2) {}; 29 | }; 30 | 31 | // NOTE: a Polygon is "open" (does not contain its border) 32 | typedef vector Polygon; 33 | 34 | inline double lensqr( const Vector &v ) { 35 | return v.x*v.x + v.y*v.y; 36 | } 37 | 38 | inline double len( const Vector &v ) { 39 | return sqrt(lensqr(v)); 40 | } 41 | 42 | inline double dotp( const Vector &v1, const Vector &v2 ) { 43 | return v1.x*v2.x + v1.y*v2.y; 44 | } 45 | 46 | inline double crossp( const Vector &v1, const Vector &v2 ) { 47 | return v1.x*v2.y - v1.y*v2.x; 48 | } 49 | 50 | inline double dotp( const Line &l, const Point &p ) { 51 | return dotp(l.c2-l.c1, p-l.c1); 52 | } 53 | 54 | inline double crossp( const Line &l, const Point &p ) { 55 | return crossp(l.c2-l.c1, p-l.c1); 56 | } 57 | 58 | inline bool parallel( const Vector &v1, const Vector &v2 ) { 59 | return fabs(crossp(v1, v2)) < EPS; 60 | } 61 | 62 | inline bool perpendicular( const Vector &v1, const Vector &v2 ) { 63 | return fabs(dotp(v1, v2)) < EPS; 64 | } 65 | 66 | inline double angle( const Vector &v1, const Vector &v2 ) { 67 | return atan2( crossp(v1, v2), dotp(v1, v2) ); 68 | } 69 | 70 | // NOTE: if lines overlap, returns false 71 | bool intersect( const Line &l1, const Line &l2 ) { 72 | double x = crossp(l1, l2.c1), y = crossp(l1, l2.c2); 73 | if( !(x < -EPS && y > EPS) && !(x > EPS && y < -EPS) ) return false; 74 | x = crossp(l2, l1.c1), y = crossp(l2, l1.c2); 75 | return (x < -EPS && y > EPS) || (x > EPS && y < -EPS); 76 | } 77 | 78 | bool intersect( Line l, const Point &p ) { 79 | if( fabs(crossp(l, p)) > EPS ) return false; 80 | if( dotp(l, p) < EPS ) return false; 81 | swap(l.c1, l.c2); 82 | return dotp(l, p) > EPS; 83 | } 84 | 85 | bool overlap( Line l1, const Line &l2 ) { 86 | if( l1.c1 == l1.c2 || l2.c1 == l2.c2 ) return false; 87 | if( fabs(crossp(l1, l2.c1)) > EPS || fabs(crossp(l1, l2.c2)) > EPS ) 88 | return false; 89 | if( dotp(l1, l2.c1) < EPS && dotp(l1, l2.c2) < EPS ) return false; 90 | swap(l1.c1, l1.c2); 91 | if( dotp(l1, l2.c1) < EPS && dotp(l1, l2.c2) < EPS ) return false; 92 | return true; 93 | } 94 | 95 | Point intersectpoint( const Line &l1, const Line &l2 ) { 96 | Point ret(INF, INF); 97 | double d1 = crossp(l1, l2.c1); 98 | double d2 = crossp(l1, l2.c2); 99 | if( fabs(d1-d2) < EPS ) return ret; 100 | ret.x = l2.c1.x + (l2.c2.x-l2.c1.x)*d1/(d1-d2); 101 | ret.y = l2.c1.y + (l2.c2.y-l2.c1.y)*d1/(d1-d2); 102 | return ret; 103 | } 104 | 105 | inline Line edge( const Polygon &p, int e ) { 106 | return Line(p[e], p[(e+1)%p.size()]); 107 | } 108 | 109 | bool degenerate( const Polygon &p ) { 110 | if( p.size() < 3 ) return true; 111 | int i, j; 112 | for( i = 0; i < p.size(); i++ ) 113 | for( j = i+1; j < p.size(); j++ ) 114 | if( p[i] == p[j] ) return true; 115 | for( i = 0; i < p.size(); i++ ) 116 | for( j = 0; j < p.size(); j++ ) 117 | if( intersect( edge(p, i), p[j] ) ) return true; 118 | for( i = 0; i < p.size(); i++ ) 119 | for( j = i+1; j < p.size(); j++ ) 120 | if( intersect( edge(p, i), edge(p, j) ) ) return true; 121 | return false; 122 | } 123 | 124 | // NOTE: assumes non-degeneracy 125 | bool inside( const Polygon &poly, const Point &p ) { 126 | int i; 127 | for( i = 0; i < poly.size(); i++ ) 128 | if( poly[i] == p || intersect(edge(poly, i), p) ) return false; 129 | Line l(p, Point(p.x+10000, p.y+1)); 130 | int n = 0; 131 | for( i = 0; i < poly.size(); i++ ) 132 | l.c2.x = max(l.c2.x, poly[i].x+10000); 133 | for( i = 0; i < poly.size(); i++ ) 134 | if( intersect(edge(poly, i), l) ) n++; 135 | return n%2; 136 | } 137 | 138 | // NOTE: assumes non-degeneracy 139 | // NOTE: negative result if p's vertices are clockwise 140 | double area( const Polygon &p ) { 141 | double x = 0; 142 | for( int i = 1; i+1 < p.size(); i++ ) 143 | x += crossp(p[i]-p[0], p[i+1]-p[0]); 144 | return x/2.0; 145 | } 146 | 147 | // NOTE: returns point indices, starting uppermost right, clockwise 148 | vector convexhull( const vector &p ) { 149 | vector ret; 150 | if( p.size() == 0 ) return ret; 151 | vector u(p.size()); 152 | Point cp = p[0]; 153 | int i, n = 0; 154 | double x; 155 | for( i = 1; i < p.size(); i++ ) 156 | if( p[i] < cp ) { 157 | cp = p[i]; 158 | n = i; 159 | } 160 | for(;;) { 161 | if( u[n] ) return ret; 162 | u[n] = true; 163 | ret.push_back(n); 164 | n = 0; 165 | for( i = 1; i < p.size(); i++ ) { 166 | x = crossp(p[n]-cp, p[i]-cp); 167 | if( x > EPS || 168 | (fabs(x) < EPS && lensqr(p[i]-cp) > lensqr(p[n]-cp)+EPS) ) 169 | n = i; 170 | } 171 | cp = p[n]; 172 | } 173 | } 174 | 175 | // clips off everything to the right of l 176 | vector clippolys( const vector &p, const Line &l ) { 177 | int i, j, k, pv, pv2, wascut; 178 | vector ret; 179 | for( i = 0; i < p.size(); i++ ) { 180 | pv = (crossp(l, p[i].back()) > EPS); 181 | wascut = 0; 182 | for( j = 0; j < p[i].size(); j++ ) { 183 | pv2 = (crossp(l, p[i][j]) > EPS); 184 | if( !pv && pv2 ) { 185 | wascut = 1; 186 | ret.push_back(Polygon()); 187 | ret.back().push_back(intersectpoint(l, 188 | Line(p[i][(j+p[i].size()-1)%p[i].size()], p[i][j]))); 189 | ret.back().push_back(p[i][k=j]); 190 | while( k=(k+1)%p[i].size(), (pv2 = (crossp(l, p[i][k]) > EPS)) ) 191 | ret.back().push_back(p[i][k]); 192 | ret.back().push_back(intersectpoint(l, 193 | Line(p[i][k], p[i][(k+1)%p[i].size()]))); 194 | if( ret.back().back() == ret.back()[0] ) 195 | ret.back().pop_back(); 196 | j = (k <= j) ? p[i].size() : k; 197 | } 198 | pv = pv2; 199 | } 200 | if( !wascut && pv ) ret.push_back(p[i]); 201 | } 202 | return ret; 203 | } 204 | -------------------------------------------------------------------------------- /old/library.cc: -------------------------------------------------------------------------------- 1 | //////////////// Contains all of my library declarations and functions for easy digestion by process.cc //////////////// 2 | 3 | //// *** Typedefs *** 4 | 5 | typedef signed long long int64; 6 | typedef unsigned long long uint64; 7 | typedef vector VI; 8 | typedef vector VVI; 9 | typedef vector VC; 10 | typedef vector VVC; 11 | typedef vector VS; 12 | typedef vector VVS; 13 | typedef vector VD; 14 | typedef vector VVD; 15 | typedef vector VLL; 16 | typedef vector VVLL; 17 | typedef vector > VPII; 18 | typedef pair PII; 19 | typedef pair > PIPII; 20 | 21 | //// *** Macros *** 22 | 23 | #define ITER(s) typeof(s.begin()) 24 | #define FORALL(s,i) for (auto i=s.begin(); i != s.end(); ++i) 25 | #define FORALLBITS(x,i) for (int xTmP=(x),i; (i=__builtin_ffs(xTmP)-1)>-1; xTmP&=xTmP-1) 26 | #define ALL(s) s.begin(), s.end() 27 | 28 | //// *** Constants *** 29 | 30 | #define PI 3.14159265358979323846 31 | #define EPS 1e-9 32 | #define INF __builtin_inf() 33 | 34 | //// *** Parsing *** 35 | 36 | //// Tokenizing strings 37 | 38 | vector Tokenize(string s, string ch) { 39 | vector ret; 40 | for (int p = 0, p2; p < s.size(); p = p2+1) { 41 | p2 = s.find_first_of(ch, p); 42 | if (p2 == -1) p2 = s.size(); 43 | if (p2-p > 0) ret.push_back(s.substr(p, p2-p)); 44 | } 45 | return ret; 46 | } 47 | 48 | vector TokenizeInt(string s, string ch) { 49 | vector ret; 50 | vector p = Tokenize(s, ch); 51 | for( int i = 0; i < p.size(); i++ ) 52 | ret.push_back(atoi(p[i].c_str())); 53 | return ret; 54 | } 55 | 56 | vector TokenizeLL(string s, string ch) { 57 | vector ret; 58 | vector p = Tokenize(s, ch); 59 | for( int i = 0; i < p.size(); i++ ) 60 | ret.push_back(StringToLL(p[i])); 61 | return ret; 62 | } 63 | 64 | vector > TokenizeMatrix(vector s, string ch) { 65 | vector > ret; 66 | for( int i = 0; i < s.size(); i++ ) 67 | ret.push_back( TokenizeInt(s[i], ch) ); 68 | return ret; 69 | } 70 | 71 | //// Transformation to/from string representation 72 | 73 | long long StringToLL(string s) { 74 | istringstream sin(s); 75 | long long ret; 76 | sin >> ret; 77 | return ret; 78 | } 79 | 80 | template string ToString(T a) { 81 | ostringstream sout; 82 | sout << a; 83 | return sout.str(); 84 | } 85 | 86 | string VCToString(const VC &a) {return string(a.begin(), a.end());} 87 | 88 | VC StringToVC(const string &s) {return VC(s.begin(), s.end());} 89 | 90 | template string VectorToString(vector v, char delim = ' ') { 91 | ostringstream sout; 92 | for (int i = 0; i < v.size(); i++) { 93 | if (i) sout << delim; 94 | sout << v[i]; 95 | } 96 | return sout.str(); 97 | } 98 | 99 | template string ArrayToString(const T* ar, int n, char delim=' ') { 100 | ostringstream sout; 101 | for (int i = 0; i < n; i++) { 102 | if (i) sout << delim; 103 | sout << ar[i]; 104 | } 105 | return sout.str(); 106 | } 107 | 108 | //// *** Misc Functions *** 109 | 110 | int IsLeapYear(int y) {return y%4 == 0 && (y%100 || y%400 == 0);} 111 | 112 | int DaysSince1600(int d, int m, int y) { 113 | // Returns # of days since Jan. 1, 1600 (ie, 1 1 1600 returns 0). 114 | static int md[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; 115 | return d-1 + md[m-1] + (y-1600)*365 + (y-(m<3)-1596)/4 - (y-(m<3)-1500)/100*3/4; 116 | } 117 | 118 | int DayOfWeek(int d, int m, int y) { 119 | // 0 = Monday, 6 = Sunday 120 | return (DaysSince1600(d, m, y)+5)%7; 121 | } 122 | 123 | string RomanNumeral(int x) { 124 | static string s[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; 125 | static int val[] ={1000,900, 500,400, 100,90, 50, 40, 10, 9, 5, 4, 1 }; 126 | string ret; 127 | for (int i = 0; x; i++) 128 | while (x >= val[i]) {x -= val[i]; ret += s[i];} 129 | return ret; 130 | } 131 | 132 | struct HashString {int operator()(const string &s) const {return hash()(s.c_str());}}; 133 | 134 | long long Rand64() { 135 | // Note that the upper bits of rand() are more reliably random. 136 | return ((long long)rand()<<33) ^ 137 | ((long long)rand()<<11) ^ 138 | ((long long)rand()>>9); 139 | } 140 | 141 | //// *** Bitwise Functions *** 142 | 143 | inline int BitCount(unsigned x) {return __builtin_popcount(x);} 144 | 145 | inline int BitCountLL(unsigned long long x) {return __builtin_popcountll(x);} 146 | 147 | inline unsigned LowestBit(unsigned x) {return x & ~(x-1);} 148 | 149 | inline unsigned long long LowestBitLL(unsigned long long x) {return x & ~(x-1);} 150 | 151 | inline unsigned ClearLowestBit(unsigned x) {return x & (x-1);} 152 | 153 | inline unsigned long long ClearLowestBitLL(unsigned long long x) {return x & (x-1);} 154 | 155 | inline int LowestBitIndex(unsigned x) {return __builtin_ffs(x)-1;} 156 | 157 | inline int LowestBitIndexLL(unsigned long long x) {return __builtin_ffsll(x)-1;} 158 | 159 | //// *** Math Functions *** 160 | 161 | //// Greatest Common Denominator 162 | 163 | template T Gcd(const T& a, const T& b) {return b != T() ? Gcd(b, a%b) : abs(a);} 164 | 165 | //// Modular functions 166 | 167 | inline int ModMult(int a, int b, int m) {return (long long)a*b%m;} 168 | 169 | int ModPow(int a, unsigned long long b, int m) { 170 | int ret = (m!=1); 171 | for(;;) { 172 | if (b&1) ret = ModMult(ret, a, m); 173 | if (!(b>>=1)) return ret; 174 | a = ModMult(a, a, m); 175 | } 176 | return ret; 177 | } 178 | 179 | inline int ModInv(int a, int p) { // Works for prime p only. 180 | return ModPow(a, p-2, p); 181 | } 182 | 183 | //// Primality and Factoring 184 | 185 | bool IsPrime(int n) { 186 | if (n <= 3) return n > 1; 187 | if ((n&1) == 0 || n%3 == 0) return false; 188 | for (int x = 5, xsq = 5*5, xsqd = 11*11 - 5*5; xsq > 0 && xsq <= n; 189 | x += 6, xsq += xsqd, xsqd += (17*17-11*11) - (11*11-5*5)) 190 | if (n%x == 0 || n%(x+2) == 0) return false; 191 | return true; 192 | } 193 | 194 | vector PrimeFactors(int n) { 195 | vector ret; 196 | while ((n&1) == 0) {ret.push_back(2); n /= 2;} 197 | while (n%3 == 0) {ret.push_back(3); n /= 3;} 198 | for (int x = 5, xsq = 5*5, xsqd = 11*11 - 5*5; xsq > 0 && xsq <= n; 199 | x += 6, xsq += xsqd, xsqd += (17*17-11*11) - (11*11-5*5)) { 200 | while (n%x == 0) {ret.push_back(x); n /= x;} 201 | while (n%(x+2)==0) {ret.push_back(x+2); n /= x+2;} 202 | } 203 | if (n > 1) ret.push_back(n); 204 | return ret; 205 | } 206 | 207 | vector UniquePrimeFactors(int n) { 208 | vector ret; 209 | if ((n&1) == 0) {ret.push_back(2); do {n /= 2;} while ((n&1) == 0);} 210 | if (n%3 == 0) {ret.push_back(3); do {n /= 3;} while (n%3 == 0);} 211 | for (int x = 5, xsq = 5*5, xsqd = 11*11 - 5*5; xsq > 0 && xsq <= n; 212 | x += 6, xsq += xsqd, xsqd += (17*17-11*11) - (11*11-5*5)) { 213 | if (n%x == 0) {ret.push_back(x); do {n /= x;} while (n%x == 0);} 214 | if (n%(x+2)==0) {ret.push_back(x+2); do {n /= x+2;} while (n%(x+2) == 0);} 215 | } 216 | if (n > 1) ret.push_back(n); 217 | return ret; 218 | } 219 | 220 | // As slow as factoring a number. 221 | int EulerPhi(int n) { 222 | int ret = n; 223 | if ((n&1) == 0) {ret >>= 1; do {n /= 2;} while ((n&1) == 0);} 224 | if (n%3 == 0) {ret /= 3; ret *= 2; do {n /= 3;} while (n%3 == 0);} 225 | for (int x = 5, xsq = 5*5, xsqd = 11*11 - 5*5; xsq > 0 && xsq <= n; 226 | x += 6, xsq += xsqd, xsqd += (17*17-11*11) - (11*11-5*5)) { 227 | if (n%x == 0) {ret /= x; ret *= x-1; do {n /= x;} while (n%x == 0);} 228 | if (n%(x+2)==0) {ret /= x+2; ret *= x+1; do {n /= x+2;} while (n%(x+2) == 0);} 229 | } 230 | if (n > 1) {ret /= n; ret *= n-1;} 231 | return ret; 232 | } 233 | 234 | //// Combinations/Permutations 235 | 236 | int Comb(int a, int b) { 237 | #define COMB__MAXA 1000 238 | #define COMB__MAXB 1000 239 | if (b > a || b < 0) return 0; 240 | if (!a) return 1; 241 | static int combmemo[COMB__MAXA+1][COMB__MAXB+1]; 242 | int &ret = combmemo[a][b]; 243 | if (!ret) ret = Comb(a-1, b-1)+Comb(a-1,b); 244 | return ret; 245 | } 246 | 247 | //// *** Matrix Functions and Linear Algebra *** 248 | 249 | template vector > MatrixAdd(const vector > &a, const vector > &b) { 250 | if (!a.size() || a.size() != b.size() || a[0].size() != b[0].size()) { 251 | return vector >(); // ERROR 252 | } 253 | vector > ret(a.size(), vector(a[0].size())); 254 | for (int i = 0; i < ret.size(); i++) 255 | for (int j = 0; j < ret[0].size(); j++) 256 | ret[i][j] = a[i][j] + b[i][j]; 257 | return ret; 258 | } 259 | 260 | template vector > MatrixMult(const vector > &a, const vector > &b) { 261 | if (!a.size() || !b.size() || a[0].size() != b.size()) { 262 | return vector >(); // ERROR 263 | } 264 | vector > ret(a.size(), vector(b[0].size())); 265 | for (int i = 0; i < ret.size(); i++) 266 | for (int j = 0; j < ret[0].size(); j++) 267 | for (int k = 0; k < a[0].size(); k++) 268 | ret[i][j] += a[i][k] * b[k][j]; 269 | return ret; 270 | } 271 | 272 | template vector > MatrixPow(vector > a, int pow) { 273 | if (!a.size() || a.size() != a[0].size()) { 274 | return vector >(); // ERROR 275 | } 276 | vector > ret(a.size(), vector(a[0].size())); 277 | for (int i = 0; i < ret.size(); i++) ret[i][i] = 1; 278 | for(;;) { 279 | if (pow&1) ret = MatrixMult(ret, a); 280 | if (!(pow>>=1)) return ret; 281 | a = MatrixMult(a, a); 282 | } 283 | return ret; 284 | } 285 | 286 | template vector > MatrixRotateCL(const vector > &a) { 287 | if (!a.size()) return a; 288 | vector > ret(a[0].size(), vector(a.size())); 289 | for (int i = 0; i < a.size(); i++) 290 | for (int j = 0; j < a[0].size(); j++) 291 | ret[j][a.size()-1-i] = a[i][j]; 292 | return ret; 293 | } 294 | 295 | template vector > MatrixRotateCCL(const vector > &a) { 296 | if (!a.size()) return a; 297 | vector > ret(a[0].size(), vector(a.size())); 298 | for (int i = 0; i < a.size(); i++) 299 | for (int j = 0; j < a[0].size(); j++) 300 | ret[i][j] = a[j][a.size()-1-i]; 301 | return ret; 302 | } 303 | 304 | template vector > MatrixTranspose(const vector > &a) { 305 | if (!a.size()) return a; 306 | vector > ret(a[0].size(), vector(a.size())); 307 | for (int i = 0; i < a.size(); i++) 308 | for (int j = 0; j < a[0].size(); j++) 309 | ret[j][i] = a[i][j]; 310 | return ret; 311 | } 312 | 313 | template vector > MatrixRotate180(vector > a) { 314 | reverse(a.begin(), a.end()); 315 | for (int i = 0; i < a.size(); i++) reverse(a[i].begin(), a[i].end()); 316 | return a; 317 | } 318 | 319 | template vector > MatrixFlipHorizontal(vector > a) { 320 | for (int i = 0; i < a.size(); i++) reverse(a[i].begin(), a[i].end()); 321 | return a; 322 | } 323 | 324 | template vector > MatrixFlipVertical(vector > a) { 325 | reverse(a.begin(), a.end()); 326 | return a; 327 | } 328 | 329 | template vector > MatrixPad(const vector >& a, T pad) { 330 | vector > ret(a.size()+2, vector(a[0].size()+2, pad)); 331 | for (int i = 0; i < a.size(); i++) 332 | for (int j = 0; j < a[0].size(); j++) 333 | ret[i+1][j+1] = a[i][j]; 334 | return ret; 335 | } 336 | 337 | //// *** Functional Optimizing *** 338 | 339 | double Func(double x) { 340 | // Your function here. 341 | } 342 | 343 | //// *** Integer with constant modulus *** 344 | 345 | // Note: MOD should be < 2^30. If division is used, MOD must be prime. 346 | template struct ModInt { 347 | int value; 348 | ModInt() : value(0) {} 349 | ModInt(int v) : value(v % MOD) {} 350 | ModInt(long long v) : value(v % MOD) {} 351 | ModInt Pow(int b) const { 352 | ModInt ret, a; ret.value = (MOD!=1); a.value = value; 353 | for(;;) {if (b&1) ret *= a; if (!(b>>=1)) return ret; a *= a;} 354 | } 355 | ModInt Inverse() const { return Pow(MOD-2); } 356 | ModInt operator+(const ModInt& m) const {return value+m.value;} 357 | ModInt& operator+=(const ModInt& m) {value = (value+m.value) % MOD; return *this;} 358 | ModInt operator-(const ModInt& m) const {return value-m.value;} 359 | ModInt& operator-=(const ModInt& m) {value = (value-m.value) % MOD; return *this;} 360 | ModInt operator-() const {return -value;} 361 | ModInt operator*(const ModInt& m) const {return (long long)value*m.value;} 362 | ModInt& operator*=(const ModInt& m) {value = ((long long)value*m.value) % MOD; return *this;} 363 | ModInt operator/(const ModInt& m) const {return *this * m.Inverse();} 364 | ModInt& operator/=(const ModInt& m) {return *this *= m.Inverse();} 365 | bool operator==(const ModInt& m) const {return toint() == m.toint();} 366 | bool operator!=(const ModInt& m) const {return toint() != m.toint();} 367 | int toint() const {return (value < 0) ? value + MOD : value;} 368 | friend ostream& operator<<(ostream& out, const ModInt& m) {out << m.toint(); return out;} 369 | }; 370 | 371 | //// *** Fraction class *** 372 | 373 | template struct Fract { 374 | T n, d; 375 | Fract(const T& n=0) : n(n), d(1) {} 376 | Fract(const T& n, const T& d, bool reduce=true) : n(n), d(d) {if (reduce) Reduce();} 377 | void Reduce() {if (d < 0) {n = -n; d = -d;} T g = Gcd(n, d); if (g != 1) {n /= g; d /= g;}} 378 | Fract operator+(const Fract& f) const {return Fract(n*f.d+f.n*d, d*f.d);} 379 | Fract& operator+=(const Fract& f) {n = n*f.d+f.n*d; d *= f.d; Reduce(); return *this;} 380 | Fract operator-(const Fract& f) const {return Fract(n*f.d-f.n*d, d*f.d);} 381 | Fract& operator-=(const Fract& f) {n = n*f.d-f.n*d; d *= f.d; Reduce(); return *this;} 382 | Fract operator-() const {return Fract(-n, d, false);} 383 | Fract operator*(const Fract& f) const {return Fract(n*f.n, d*f.d);} 384 | Fract& operator*=(const Fract& f) {n *= f.n; d *= f.d; Reduce(); return *this;} 385 | Fract operator/(const Fract& f) const {return Fract(n*f.d, d*f.n);} 386 | Fract& operator/=(const Fract& f) {n *= f.d; d *= f.n; Reduce(); return *this;} 387 | bool operator<(const Fract& f) const {return n*f.d < d*f.n;} 388 | bool operator<=(const Fract& f) const {return n*f.d <= d*f.n;} 389 | bool operator>(const Fract& f) const {return n*f.d > d*f.n;} 390 | bool operator>=(const Fract& f) const {return n*f.d >= d*f.n;} 391 | bool operator==(const Fract& f) const {return n == f.n && d == f.d;} 392 | bool operator!=(const Fract& f) const {return n != f.n || d != f.d;} 393 | double todouble() const {return (double)n/(double)d;} 394 | friend Fract abs(const Fract& f) {return Fract(abs(f.n), f.d, false);} 395 | friend ostream& operator<<(ostream& out, const Fract& f) {out << f.n; if (f.d != 1) out << '/' << f.d; return out;} 396 | }; 397 | 398 | //// *** Simple Bigint (string-based) class *** 399 | 400 | struct SimpleBigInt { 401 | bool neg; 402 | string dig; 403 | SimpleBigInt() : dig("0"), neg(false) {} 404 | SimpleBigInt(int x) 405 | {if ((neg=x<0)) x=-x; do {dig.push_back(x%10+'0'); x /= 10;} while (x); reverse(dig.begin(), dig.end());} 406 | SimpleBigInt(long long x) 407 | {if ((neg=x<0)) x=-x; do {dig.push_back(x%10+'0'); x /= 10;} while (x); reverse(dig.begin(), dig.end());} 408 | SimpleBigInt(const string& s) {if ((neg=(s[0]=='-'))) dig = s.substr(1); else dig = s;} 409 | SimpleBigInt(const string& dig, bool neg) : dig(dig), neg(neg) {} 410 | static bool LessThan(const string& a, bool an, const string& b, bool bn, bool count_eq) { 411 | if (an != bn) return an; 412 | if (a.size() != b.size()) return (a.size() < b.size()) ^ an; 413 | for (int i = 0; i < a.size(); i++) if (a[i] != b[i]) return (a[i] < b[i]) ^ an; 414 | return count_eq; 415 | } 416 | static SimpleBigInt AddOrSubtract(const string& a, bool an, const string& b, bool bn) { 417 | SimpleBigInt ret("", an); 418 | if (an == bn) { 419 | for (int i = 0, c = 0; i < a.size() || i < b.size() || c; i++) { 420 | if (i < a.size()) c += a[a.size()-1-i]-'0'; 421 | if (i < b.size()) c += b[b.size()-1-i]-'0'; 422 | ret.dig += c%10 + '0'; c /= 10; 423 | } 424 | } else { 425 | bool swp = LessThan(a, false, b, false, an); 426 | if (swp) ret.neg = bn; 427 | const string& s1 = (swp ? b : a), s2 = (swp ? a : b); 428 | for (int i = 0, c = 0; i < s1.size(); i++) { 429 | c += 10 + s1[s1.size()-1-i]-'0'; 430 | if (i < s2.size()) c -= s2[s2.size()-1-i]-'0'; 431 | ret.dig += c%10 + '0'; c = c/10-1; 432 | } 433 | for (int i = ret.dig.size()-1; i >= 0; i--) 434 | if (i==0 || ret.dig[i]!='0') {ret.dig = ret.dig.substr(0, i+1); break;} 435 | } 436 | reverse(ret.dig.begin(), ret.dig.end()); 437 | return ret; 438 | } 439 | SimpleBigInt operator+(const SimpleBigInt& b) const {return AddOrSubtract(dig, neg, b.dig, b.neg);} 440 | SimpleBigInt& operator+=(const SimpleBigInt& b) {*this = AddOrSubtract(dig, neg, b.dig, b.neg); return *this;} 441 | SimpleBigInt operator-(const SimpleBigInt& b) const {return AddOrSubtract(dig, neg, b.dig, !b.neg);} 442 | SimpleBigInt& operator-=(const SimpleBigInt& b) {*this = AddOrSubtract(dig, neg, b.dig, !b.neg); return *this;} 443 | SimpleBigInt operator-() const {return SimpleBigInt(dig, !(neg || dig=="0"));} 444 | SimpleBigInt operator*(int x) const { // NOTE: x*10 should not overflow int. 445 | if (x == 0) return SimpleBigInt(); 446 | SimpleBigInt ret("", neg); 447 | if (x < 0) {x = -x; ret.neg = !neg && dig != "0";} 448 | for (int i = 0, c = 0; i < dig.size() || c; i++) { 449 | if (i < dig.size()) c += x * (dig[dig.size()-1-i]-'0'); 450 | ret.dig += c%10 + '0'; c /= 10; 451 | } 452 | reverse(ret.dig.begin(), ret.dig.end()); 453 | return ret; 454 | } 455 | SimpleBigInt& operator*=(int x) {return *this = *this * x;} 456 | SimpleBigInt operator*(const SimpleBigInt& b) const { 457 | if (b == 0 || *this == 0) return SimpleBigInt(); 458 | SimpleBigInt ret; 459 | for (int i = 0; i < b.dig.size(); i++) { 460 | char ch = b.dig[b.dig.size()-1-i]; 461 | if (ch == '0') continue; 462 | SimpleBigInt v = *this * (int)(ch-'0'); 463 | for (int j = 0; j < i; j++) v.dig += '0'; 464 | ret += v; 465 | } 466 | if (b.neg) ret.neg = !ret.neg; 467 | return ret; 468 | } 469 | SimpleBigInt& operator*=(const SimpleBigInt& b) {return *this = *this * b;} 470 | SimpleBigInt operator/(SimpleBigInt b) const { 471 | if (b == 0 || *this == 0) return SimpleBigInt(); 472 | SimpleBigInt ret("", neg ^ b.neg), rem(dig, false); 473 | b.neg = false; 474 | int d = 0; 475 | while (b <= rem) {b.dig += '0'; d++;} 476 | if (d == 0) return SimpleBigInt(); 477 | ret.dig = string(d, '0'); 478 | for (d--; d >= 0; d--) { 479 | b.dig.resize(b.dig.size()-1); 480 | while (b <= rem) {rem -= b; ret.dig[ret.dig.size()-1-d]++;} 481 | } 482 | return ret; 483 | } 484 | SimpleBigInt& operator/=(const SimpleBigInt& b) {return *this = *this / b;} 485 | SimpleBigInt operator%(const SimpleBigInt& b) const {return *this - b * (*this / b);} 486 | SimpleBigInt& operator%=(const SimpleBigInt& b) {return *this -= b * (*this / b);} 487 | bool operator<(const SimpleBigInt& b) const {return LessThan(dig, neg, b.dig, b.neg, false);} 488 | bool operator<=(const SimpleBigInt& b) const {return LessThan(dig, neg, b.dig, b.neg, true);} 489 | bool operator>(const SimpleBigInt& b) const {return !LessThan(dig, neg, b.dig, b.neg, true);} 490 | bool operator>=(const SimpleBigInt& b) const {return !LessThan(dig, neg, b.dig, b.neg, false);} 491 | bool operator==(const SimpleBigInt& b) const {return neg == b.neg && dig == b.dig;} 492 | bool operator!=(const SimpleBigInt& b) const {return neg != b.neg || dig != b.dig;} 493 | string tostring() const {return (neg ? "-" : "") + dig;} 494 | friend SimpleBigInt abs(const SimpleBigInt& b) {return SimpleBigInt(b.dig, false);} 495 | friend istream& operator>>(istream& in, SimpleBigInt& b) {string s; in >> s; b = SimpleBigInt(s); return in;} 496 | friend ostream& operator<<(ostream& out, const SimpleBigInt& b) {if (b.neg) out << '-'; out << b.dig; return out;} 497 | }; 498 | 499 | //// *** Polynomial class *** 500 | 501 | template struct Polynomial { 502 | vector co; 503 | Polynomial() : co() {} 504 | Polynomial(const T& x) : co(1, x) {Simplify();} 505 | Polynomial(const T& x, const T& y) : co(2) {co[1] = x; co[0] = y; Simplify();} 506 | Polynomial(const vector& v) : co(v) {Simplify();} 507 | T Eval(const T& x) const {T ret = T(); for (int i = co.size()-1; i >= 0; i--) {ret *= x; ret += co[i];} return ret;} 508 | void Simplify() {while (co.size() && co.back() == T()) co.pop_back();} 509 | Polynomial operator+(const Polynomial& p) const {Polynomial ret = *this; return ret += p;} 510 | Polynomial& operator+=(const Polynomial& p) { 511 | if (p.co.size() > co.size()) co.resize(p.co.size()); 512 | for (int i = 0; i < p.co.size(); i++) co[i] += p.co[i]; 513 | Simplify(); 514 | return *this; 515 | } 516 | Polynomial operator-(const Polynomial& p) const {Polynomial ret = *this; return ret -= p;} 517 | Polynomial& operator-=(const Polynomial& p) { 518 | if (p.co.size() > co.size()) co.resize(p.co.size()); 519 | for (int i = 0; i < p.co.size(); i++) co[i] -= p.co[i]; 520 | Simplify(); 521 | return *this; 522 | } 523 | Polynomial operator-() const 524 | {Polynomial ret = *this; for (int i = 0; i < ret.co.size(); i++) ret.co[i] = -ret.co[i]; return ret;} 525 | Polynomial operator*(const T& x) const {Polynomial ret = *this; return ret *= x;} 526 | Polynomial& operator*=(const T& x) {for (int i = 0; i < co.size(); i++) co[i] *= x; Simplify(); return *this;} 527 | Polynomial operator/(const T& x) const {Polynomial ret = *this; return ret /= x;} 528 | Polynomial& operator/=(const T& x) {for (int i = 0; i < co.size(); i++) co[i] /= x; Simplify(); return *this;} 529 | Polynomial operator*(const Polynomial& p) const { 530 | if (!co.size() || !p.co.size()) return Polynomial(); 531 | Polynomial ret; 532 | ret.co.resize(co.size() + p.co.size() - 1); 533 | for (int i = 0; i < co.size(); i++) 534 | for (int j = 0; j < p.co.size(); j++) 535 | ret.co[i+j] += co[i] * p.co[j]; 536 | ret.Simplify(); 537 | return ret; 538 | } 539 | Polynomial& operator*=(const Polynomial& p) {*this = *this * p; return *this;} 540 | friend ostream& operator<<(ostream& out, const Polynomial& p) { 541 | if (!p.co.size()) {out << 0; return out;} 542 | for (int i = p.co.size()-1; i >= 0; i--) if (p.co[i] != T()) { 543 | if (i < p.co.size()-1 || p.co[i] < 0) out << ((p.co[i] < 0) ? '-' : '+'); 544 | if (abs(p.co[i]) != T(1) || i == 0) out << abs(p.co[i]); 545 | if (i > 0) out << 'x'; 546 | if (i > 1) out << '^' << i; 547 | } 548 | return out; 549 | } 550 | }; 551 | 552 | template Polynomial PolynomialDerivative(const Polynomial& p) { 553 | Polynomial ret; 554 | for (int i = 1; i < p.co.size(); i++) 555 | ret.co.push_back(p.co[i] * i); 556 | ret.Simplify(); 557 | return ret; 558 | } 559 | 560 | // Note: Returns the integral with constant coefficient 0. 561 | template Polynomial PolynomialIntegral(const Polynomial& p) { 562 | Polynomial ret; 563 | ret.co.push_back(T()); 564 | for (int i = 0; i < p.co.size(); i++) 565 | ret.co.push_back(p.co[i] / (i+1)); 566 | ret.Simplify(); 567 | return ret; 568 | } 569 | 570 | template Polynomial PolynomialSubstitute(const Polynomial& p, const Polynomial& x) { 571 | Polynomial xpow(1), ret; 572 | for (int i = 0; i < p.co.size(); i++) { 573 | if (i) xpow *= x; 574 | ret += xpow * p.co[i]; 575 | } 576 | ret.Simplify(); 577 | return ret; 578 | } 579 | 580 | // Note: T must support division. 581 | template Polynomial PolynomialSum0ToX(const Polynomial& p) { 582 | static vector > powers_of_x_plus_one; 583 | static vector > power_sums; 584 | if (powers_of_x_plus_one.size() == 0) 585 | powers_of_x_plus_one.push_back(Polynomial(1)); 586 | if (powers_of_x_plus_one.size() == 1) 587 | powers_of_x_plus_one.push_back(Polynomial(vector(2, 1))); 588 | for (int i = powers_of_x_plus_one.size(); i <= p.co.size(); i++) 589 | powers_of_x_plus_one.push_back(powers_of_x_plus_one[i-1] * 590 | powers_of_x_plus_one[1]); 591 | for (int n = power_sums.size(); n < p.co.size(); n++) { 592 | power_sums.push_back(powers_of_x_plus_one[n+1]); 593 | for (int i = 0; i < n; i++) 594 | power_sums.back() -= power_sums[i] * powers_of_x_plus_one[n+1].co[i]; 595 | for (int i = 0; i <= n+1; i++) 596 | power_sums.back().co[i] /= n+1; 597 | } 598 | Polynomial ret; 599 | for (int i = 0; i < p.co.size(); i++) ret += power_sums[i] * p.co[i]; 600 | return ret; 601 | } 602 | 603 | template string PolynomialToString(const Polynomial& p) { 604 | ostringstream out; 605 | out << p; 606 | return out.str(); 607 | } 608 | 609 | //// *** Algorithms *** 610 | 611 | //// Bipartite Matching 612 | 613 | // Returns -1 for unmatched items. 614 | // Complexity: O(V*E) 615 | VI BipartiteMatch(const VVI &mat, VI *back_match = NULL) { 616 | int max_item = -1; 617 | VI fmat(mat.size(), -1), seen(mat.size(), -1), prev(mat.size()); 618 | for (int i = 0; i < mat.size(); i++) if (mat[i].size()) 619 | max_item >?= *max_element(mat[i].begin(), mat[i].end()); 620 | VI bmat(max_item+1, -1); 621 | 622 | for (int i = 0; i < mat.size(); i++) { 623 | VI q(1, i); 624 | seen[i] = i; prev[i] = -1; 625 | int x, y; 626 | while (!q.empty()) { 627 | x = q.back(); q.pop_back(); 628 | for (VI::const_iterator it = mat[x].begin(); it != mat[x].end(); ++it) { 629 | int bm = bmat[*it]; 630 | if (bm == -1) {y = *it; goto found_match;} 631 | if (seen[bm] < i) { 632 | seen[bm] = i; prev[bm] = x; 633 | q.push_back(bm); 634 | } 635 | } 636 | } 637 | continue; 638 | found_match: 639 | while (x != -1) { 640 | bmat[y] = x; 641 | swap(y, fmat[x]); 642 | x = prev[x]; 643 | } 644 | } 645 | 646 | if (back_match) *back_match = bmat; 647 | return fmat; 648 | } 649 | 650 | -------------------------------------------------------------------------------- /old/math.cc: -------------------------------------------------------------------------------- 1 | int gcd(int a, int b) { 2 | int n; 3 | while( b ) { 4 | n = b; 5 | b = a%b; 6 | a = n; 7 | } 8 | return abs(a); 9 | } 10 | 11 | // Returned values will satisfy x*a+y*b = d. |x|+|y| will be as small as 12 | // possible. Ties are broken by x <= y. 13 | // All other solutions are of the form (x+n*(b/d))*a + (y-n*(a/d))*b = d. 14 | int extendedgcd(int a, int b, int &x, int &y) { 15 | if( !b ) { 16 | x = (a==0)?0:(a<0)?-1:1; y = 0; 17 | return abs(a); 18 | } 19 | int ret = extendedgcd(b, a%b, x, y); 20 | x -= y*(a/b); 21 | swap(x, y); 22 | return ret; 23 | } 24 | 25 | unsigned modinv(unsigned a, unsigned n) { 26 | unsigned on=n; 27 | unsigned ax=1, nx=0, d, tmp; 28 | while( n ) { 29 | d = a/n; 30 | tmp = n; n = a - d*n; a = tmp; 31 | tmp = nx; nx = (ax + d*(i64)(on-nx))%on; ax = tmp; 32 | } 33 | return ax%(on/a); 34 | } 35 | 36 | bool isprime(int n) { 37 | n = abs(n); 38 | if( n <= 3 ) return( n >= 2 ); 39 | if( n%2 == 0 ) return false; 40 | if( n%3 == 0 ) return false; 41 | for( unsigned i = 5; i*i <= n; i += 6 ) { 42 | if( n%i == 0 ) return false; 43 | if( n%(i+2) == 0 ) return false; 44 | } 45 | return true; 46 | } 47 | 48 | vector factorize(int n) { 49 | vector ret; 50 | 51 | n = abs(n); 52 | if( n < 2 ) return ret; 53 | while( n%2 == 0 ) {ret.push_back(2); n /= 2;} 54 | while( n%3 == 0 ) {ret.push_back(3); n /= 3;} 55 | for( int i = 5; i*i <= n; i += 6 ) { 56 | while( n%i == 0 ) {ret.push_back(i); n /= i;} 57 | while( n%(i+2) == 0 ) {ret.push_back(i+2); n /= i+2;} 58 | } 59 | if( n > 1 ) ret.push_back(n); 60 | return ret; 61 | } 62 | 63 | i64 num_permutations(int n, int r) { 64 | if( r < 0 || n < r ) return 0; 65 | i64 ret = 1; 66 | for( int i = n; i > n-r; i-- ) ret *= i; 67 | return ret; 68 | } 69 | 70 | i64 num_combinations(int n, int r) { 71 | if( r < 0 || n < r ) return 0; 72 | if( n-r < r ) r = n-r; 73 | vector fact(r); 74 | int i, j, k, x; 75 | for( i = 0; i < r; i++ ) fact[i] = n-i; 76 | for( i = 1; i <= r; i++ ) { 77 | x = i; 78 | for( j = 2; j <= x; j++ ) while( x%j == 0 ) { 79 | x /= j; 80 | for( k = 0; k < r; k++ ) if( fact[k]%j == 0 ) break; 81 | fact[k] /= j; 82 | } 83 | } 84 | i64 ret = 1; 85 | for( i = 0; i < r; i++ ) ret *= fact[i]; 86 | return ret; 87 | } 88 | 89 | inline unsigned modmult(unsigned a, unsigned b, unsigned n) { 90 | return (unsigned)(((i64)a*(i64)b)%n); 91 | } 92 | 93 | inline unsigned modadd(unsigned a, unsigned b, unsigned n) { 94 | return (unsigned)(((i64)a+(i64)b)%n); 95 | } 96 | 97 | unsigned modpow(unsigned a, unsigned e, unsigned n) { 98 | vector p; 99 | unsigned b = a%n, c = 1, i; 100 | i64 x; 101 | 102 | for( i = 0, x = 1; x <= e; x *= 2, i++ ) { 103 | p.push_back(b); 104 | b = modmult(b, b, n); 105 | } 106 | while( e ) { 107 | x /= 2; i--; 108 | if( e >= x ) { 109 | c = modmult(c, p[i], n); 110 | e -= x; 111 | } 112 | } 113 | return c; 114 | } 115 | 116 | unsigned eulerphi(unsigned n) { 117 | unsigned phi = n, p; 118 | for( p = 2; p*p <= n; p++ ) if( n%p == 0 ) { 119 | phi = (phi/p)*(p-1); 120 | while( n%p == 0 ) n /= p; 121 | } 122 | if( n >= 2 ) phi = (phi/n)*(n-1); 123 | return phi; 124 | } 125 | 126 | // Fills array with partition function p(n) for 0 <= n <= N 127 | int part[122]; // 121 is max partition that will fit into int 128 | void getpartitions(int N) { 129 | part[0] = 1; 130 | for( int n = 1; n <= N; n++ ) { 131 | part[n] = 0; 132 | for( int k = 1, x; k <= n; k++ ) { 133 | x = n-k*(3*k-1)/2; 134 | if( x < 0 ) break; 135 | if( k&1 ) part[n] += part[x]; else part[n] -= part[x]; 136 | x = n-k*(3*k+1)/2; 137 | if( x < 0 ) break; 138 | if( k&1 ) part[n] += part[x]; else part[n] -= part[x]; 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /old/misc.cc: -------------------------------------------------------------------------------- 1 | // SORT TOOLS 2 | // Comparison function 3 | class cmp : binary_function { 4 | public: 5 | bool operator()(T a, T b) const { 6 | } 7 | }; 8 | 9 | // Functions to convert two vectors into a vector of pairs, and vice versa 10 | template 11 | vector > topair(const vector &v1, const vector &v2) { 12 | vector > ret; 13 | vector::const_iterator it1; 14 | vector::const_iterator it2; 15 | for( it1 = v1.begin(), it2 = v2.begin(); 16 | it1 != v1.end() && it2 != v2.end(); it1++, it2++ ) 17 | ret.push_back(pair(*it1, *it2)); 18 | return ret; 19 | } 20 | 21 | template 22 | void frompair(const vector > &v, vector &v1, vector &v2) { 23 | v1.clear(); v2.clear(); 24 | for( vector >::const_iterator it = v.begin(); 25 | it != v.end(); it++ ) { 26 | v1.push_back(it->first); 27 | v2.push_back(it->second); 28 | } 29 | } 30 | 31 | // Useful for sorting one vector by a second vector of priorities 32 | template 33 | void sortby(vector &v, vector &priority) { 34 | vector > pv = topair(priority, v); 35 | sort(pv.begin(), pv.end()); 36 | frompair(pv, priority, v); 37 | } 38 | 39 | 40 | // RECTANGULAR ARRAY STUFF 41 | vector buffer(const vector &m, char b) { 42 | if( m.size() == 0 || m[0].size() == 0 ) 43 | return vector(1, string()+b); 44 | string s; 45 | int i, j; 46 | for( i = 0; i < m[0].size()+2; i++ ) s += b; 47 | vector buf(m.size()+2, s); 48 | for( j = 0; j < m.size(); j++ ) 49 | for( i = 0; i < m[0].size(); i++ ) 50 | buf[j+1][i+1] = m[j][i]; 51 | return buf; 52 | } 53 | 54 | vector rotatecl(const vector &m) { 55 | vector ret(m[0].size()); 56 | for( int y = 0; y < m[0].size(); y++ ) 57 | for( int x = 0; x < m.size(); x++ ) 58 | ret[y] += m[m.size()-1-x][y]; 59 | return ret; 60 | } 61 | 62 | vector rotateccl(const vector &m) { 63 | vector ret(m[0].size()); 64 | for( int y = 0; y < m[0].size(); y++ ) 65 | for( int x = 0; x < m.size(); x++ ) 66 | ret[y] += m[x][m[0].size()-1-y]; 67 | return ret; 68 | } 69 | 70 | vector rotate180(const vector &m) { 71 | vector ret(m.size()); 72 | for( int y = 0; y < m.size(); y++ ) 73 | for( int x = 0; x < m[0].size(); x++ ) 74 | ret[y] += m[m.size()-1-y][m[0].size()-1-x]; 75 | reverse(m.begin(), m.end(); 76 | } 77 | 78 | vector transpose(const vector &m) { 79 | vector ret(m[0].size()); 80 | for( int y = 0; y < m[0].size(); y++ ) 81 | for( int x = 0; x < m.size(); x++ ) 82 | ret[y] += m[x][y]; 83 | return ret; 84 | } 85 | 86 | int tobitmap(const string &s, const string &ones) { 87 | int ret = 0; 88 | for( int i = 0, x = 1; i < s.size(); i++, x <<= 1 ) 89 | if( ones.find(s[i]) != -1 ) ret += x; 90 | return ret; 91 | } 92 | 93 | int tobitmap(const vector &s, const string &ones) { 94 | int ret = 0; 95 | for( int i = 0, x = 1; i < s.size(); i++, x <<= 1 ) 96 | for( int j = 0; j < s[0].size(); j++, x <<= 1 ) 97 | if( ones.find(s[i][j]) != -1 ) ret += x; 98 | return ret; 99 | } 100 | 101 | string frombitmap(int b, int n, char one, char zero) { 102 | string ret; 103 | for( ; n > 0; n--, b >>= 1 ) ret += (b&1)?one:zero; 104 | return ret; 105 | } 106 | 107 | vector frombitmap(int b, int xn, int yn, char one, char zero) { 108 | vector ret(yn); 109 | for( int y = 0; y < yn; y++, b >>= 1 ) 110 | for( int x = 0; x < xn; x++, b >>= 1 ) 111 | ret[y] += (b&1)?one:zero; 112 | return ret; 113 | } 114 | 115 | 116 | // HEX COORDINATES 117 | // NOTE: x is east, y is northeast 118 | int hdx[6] = {1, 0, -1, -1, 0, 1}; 119 | int hdy[6] = {0, 1, 1, 0, -1, -1}; 120 | 121 | void hexrotateccl(int &x, int &y, int steps) { 122 | int x2 = hdx[steps]*x + hdx[(steps+1)%6]*y; 123 | y = hdy[steps]*x + hdy[(steps+1)%6]*y; 124 | x = x2; 125 | } 126 | 127 | int hexdist(int x, int y) { 128 | int ret = abs(x)+abs(y); 129 | ret = min(ret, abs(y)+abs(x+y)); 130 | return min(ret, abs(x+y)+abs(x)); 131 | } 132 | 133 | 134 | // CARDS 135 | // NOTE: h must always be hand of 5 cards 136 | string rankval = "A23456789TJQKA"; 137 | string suitval = "CDHS"; 138 | 139 | inline int cardval(string c) { 140 | return rankval.find(c[0]) + suitval.find(c[1])*13; 141 | } 142 | 143 | enum {HighCard, Pair, TwoPair, ThreeOfAKind, Straight, Flush, 144 | FullHouse, FourOfAKind, StraightFlush}; 145 | int ratehand( VI h ) { 146 | VI r(13), n(5); 147 | bool flush = true, straight; 148 | int i, j, x, rs=12, re=0; 149 | for( i = 1; i < 5; i++ ) if( h[i]/13 != h[i-1]/13 ) flush = false; 150 | for( i = 0; i < 5; i++ ) { 151 | x = h[i]%13; 152 | n[++r[x]]++; 153 | rs = min(rs, x); 154 | re = max(re, x); 155 | } 156 | if( n[2] == 0 ) { 157 | if( re-rs == 4 ) straight = true; 158 | else if( r[0] && r[9] && r[10] && r[11] && r[12] ) straight = true; 159 | } 160 | if( flush && straight ) return StraightFlush; 161 | if( n[4] == 1 ) return FourOfAKind; 162 | if( n[3] == 1 && n[2] == 2 ) return FullHouse; 163 | if( flush ) return Flush; 164 | if( straight ) return Straight; 165 | if( n[3] == 1 ) return ThreeOfAKind; 166 | if( n[2] == 2 ) return TwoPair; 167 | if( n[2] ) return Pair; 168 | return HighCard; 169 | } 170 | 171 | inline bool isflush( VI h ) { 172 | int x = h[0]/13; 173 | return x==h[1]/13 && x==h[2]/13 && x==h[3]/13 && x==h[4]/13; 174 | } 175 | 176 | inline bool isstraight( VI h ) { 177 | VI r(13); 178 | int rs=12, re=0; 179 | for( int i = 0; i < h.size(); i++ ) { 180 | int x = h[i]%13; 181 | if( r[x]++ ) return false; 182 | rs = min(rs, x); 183 | re = max(re, x); 184 | } 185 | if( re-rs == 4 ) return true; 186 | return r[0] && r[9] && r[10] && r[11] && r[12]; 187 | } 188 | 189 | bool cardcmp( int c1, int c2 ) { 190 | int x = c1%13, y = c2%13; 191 | x = (x==0)?13:x; 192 | y = (y==0)?13:y; 193 | if( x != y ) return x < y; 194 | return c1/13 < c2/13; 195 | } 196 | 197 | // NOTE: poker tie-breaker returns the highest card of the largest match, 198 | // except in the case of straights with low ace 199 | int tiebreaker( VI h ) { 200 | VI r(13), n(5, -1); 201 | int i; 202 | for( i = 0; i < h.size(); i++ ) { 203 | int x = h[i]%13; 204 | r[x]++; 205 | int &y = n[r[x]]; 206 | if( y == -1 || cardcmp(y, h[i]) ) y = h[i]; 207 | } 208 | if( r[0] && r[1] && r[2] && r[3] && r[4] ) 209 | for( i = 0; i < h.size(); i++ ) 210 | if( h[i]%13 == 4 ) return i; 211 | for( i = 4; ; i-- ) 212 | if( n[i] != -1 ) return n[i]; 213 | } 214 | 215 | bool handcmp( VI h1, VI h2 ) { 216 | int x = ratehand(h1), y = ratehand(h2); 217 | if( x != y ) return x < y; 218 | return cardcmp(tiebreaker(h1), tiebreaker(h2)); 219 | } 220 | 221 | // HASH TOOLS 222 | // String hash function 223 | class hash : hash { 224 | public: 225 | size_t operator()(const string &s) const { 226 | return ((hash)*this)(s.c_str()); 227 | } 228 | }; 229 | -------------------------------------------------------------------------------- /old/rangeop.cc: -------------------------------------------------------------------------------- 1 | // RangeOp is a data structure built on an array and an associative operation. 2 | // It takes linear setup time, linear memory, then allows for log-time 3 | // updates, and log-time calculation of the operation on arbitrary ranges. 4 | // It also has constant amortized time when you merely increment the front 5 | // and/or back of ranges. 6 | // T will be the data type for the operation. 7 | // op will be the associative (but not necessarily commutative) binary 8 | // operation. 9 | // def, the "default value" for an empty range, must be the identity under op. 10 | // ie, it should satisfy op(x, def) == x == op(def, x). Be careful to 11 | // specify it properly depending on your operation. 12 | // 13 | // Example declarations: 14 | // 15 | // RangeOp > r(v.size()); 16 | // r.set(0, v.begin(), v.end()); 17 | // Creates a RangeOp, using the addition operation, from a known 18 | // vector v. Note that the default is assumed to be 0. Also note 19 | // that this initialiation is nice and linear in time/memory. 20 | // x = r.calc(2, 5); 21 | // x is now equal to v[2]+v[3]+v[4] 22 | // 23 | // RangeOp > r(1000, 1); 24 | // Product operation - note that default value has to be 1. The 25 | // default value is ALWAYS used as a basis for range calculations; 26 | // if it were left as 0, all ranges would return 0. 27 | // 28 | // int min(const int &a, const int &b) {return min(a,b);} 29 | // RangeOp r(1000, 2147483647, min); 30 | // The easiest way to specify your own operator. In this case, min. 31 | // Note the default value. 32 | // 33 | // Memory use: RangeOp stores an internal array of T. Its size is the smallest 34 | // power of 2 that is at least twice the maximum number of elements. (So, 35 | // it's never larger than 4 times a normal array size) 36 | // 37 | // Time complexity: 38 | // (n is the maximum size of the RangeOp, m is the size of any given range) 39 | // RangeOp constructor: O(n) 40 | // Calculating a range: O(log m) 41 | // Getting a value: O(1) 42 | // Setting a value: O(log n) 43 | // Setting a range: O(m log n), and no worse than O(n) 44 | // Also, computing a series of distinct ranges with endpoints that change 45 | // monotonically is never worse than O(n). That is, calculating ranges that 46 | // are sliding along the array takes amortized CONSTANT time. 47 | // 48 | // Things to watch for: 49 | // - Don't call calc with q < p. 50 | // - Always set the default value properly. 51 | // - Updating values clears the internal "cache", which clashes with the above 52 | // amortized-constant-time guarantee. 53 | // - 2-D RangeOps would require some additional annoying code (you'd need to 54 | // change RangeOp to support ==, =, and a "lifted" version of op) 55 | 56 | template struct RangeOp { 57 | Op op; 58 | T *t, c[32], def; 59 | int s, cs[32], ce[32], cv; 60 | 61 | RangeOp(int n, T def=T(), Op op=Op()) : cv(0), def(def), op(op) { 62 | for (s=1; s>1, b=(ce[d]=b)>>1; 72 | if ((cs[d]=a)==(ce[d]=b)) c[d]=def; 73 | if (cvq?c[d]:op(c[d],t[b++])); 77 | } 78 | return c[0]; 79 | } 80 | 81 | // optional: for setting a range of values at once 82 | template void set(int p, it i, it j) { 83 | int q=p+=s; 84 | for (; i!=j; ++i) t[q++]=*i; 85 | for (cv=0; q=q+1>>1,p>>=1;) 86 | for (int k=p; k>=1;) 94 | if ((v=op(t[p*2],t[p*2+1]))==t[p]) break; 95 | } 96 | }; 97 | -------------------------------------------------------------------------------- /old/rangeop2.cc: -------------------------------------------------------------------------------- 1 | // Structure that takes O(N) setup time, O(N) memory, then allows for O(logN) 2 | // calculation of a given associative operation on arbitrary ranges. Also 3 | // has constant amortized time when successively incrementing the front 4 | // and/or back of ranges. 5 | template 6 | class RangeOp { 7 | public: 8 | vector > tree; 9 | T (*op)(const T &, const T &); 10 | T def; // should have the property that op(x, def) == x == op(def, x) 11 | 12 | // internal cache that allows for amortized runtimes 13 | vector cs, ce; 14 | vector cache; 15 | 16 | // pass in start/end iterators, the (associative) operation, and (if 17 | // necessary) a default (identity) T value for empty ranges 18 | template 19 | RangeOp(it s, it e, T (*op)(const T &, const T &), T def = T()) 20 | : op(op), def(def) { 21 | tree.push_back(vector()); 22 | for( ; s != e; s++ ) tree[0].push_back(*s); 23 | for( int depth = 1, i; tree[depth-1].size() > 1; depth++ ) { 24 | tree.push_back(vector((tree[depth-1].size()+1)/2)); 25 | for( i = 0; i+1 < tree[depth-1].size(); i += 2 ) 26 | tree[depth][i>>1] = op(tree[depth-1][i], tree[depth-1][i+1]); 27 | if( i < tree[depth-1].size() ) tree[depth][i>>1] = tree[depth-1][i]; 28 | } 29 | cs = ce = vector(tree.size()+1); 30 | cache = vector(tree.size()+1, def); 31 | } 32 | 33 | // takes O(log(e-s)) time (and possibly constant time, amortized) 34 | T dorange(int s, int e) { 35 | if( s >= e ) return def; 36 | int depth, curs, cure; 37 | for( depth = 0; ; depth++ ) { 38 | curs = ((s+(1<>depth); 39 | cure = (e>>depth); 40 | if( curs == cure ) { 41 | cache[depth] = def; 42 | cs[depth] = curs; 43 | ce[depth] = cure; 44 | } 45 | if( curs == cs[depth] && cure == ce[depth] ) break; 46 | } 47 | for( depth--; depth >= 0; depth-- ) { 48 | curs <<= 1; cure <<= 1; 49 | int &v = cache[depth]; 50 | v = cache[depth+1]; 51 | if( ((curs-1)<= s ) v = op(tree[depth][--curs], v); 52 | if( ((cure+1)< 2 | #include 3 | 4 | // Structure that takes O(N) setup time, O(N) memory, then allows for O(logN) 5 | // calculation of a given associative operation on arbitrary ranges. Also 6 | // has constant amortized time when successively incrementing the front 7 | // and/or back of ranges. 8 | // op is the associative (but not necessarily commutative) function to apply 9 | // def is the default value, and should satisfy op(x, def) == x == op(def, x) 10 | template struct RangeOp { 11 | T *t, (*op)(T&,T&), def, c[32]; 12 | int s, cs[32], ce[32], cv; 13 | 14 | RangeOp(int n, T (*op)(T&,T&), T def=T()) : op(op), def(def), cv(0) { 15 | for (s=1; s>=1;) 22 | if ((v=op(t[p*2],t[p*2+1]))==t[p]) break; 23 | } 24 | template void set(int p, it i, it j) { 25 | int q=p+=s; 26 | for (; i!=j; ++i) t[q++]=*i; 27 | for (cv=0; q=q+1>>1,p>>=1;) 28 | for (int k=p; k=cv||a!=cs[d]||b!=ce[d]); d++) 34 | a=(cs[d]=a)+1>>1, b=(ce[d]=b)>>1; 35 | if ((cs[d]=a)==(ce[d]=b)) c[d]=def; 36 | if (cvq?c[d]:op(c[d],t[b++])); 40 | } 41 | return c[0]; 42 | } 43 | }; 44 | 45 | int plus(int &a, int &b) {return a+b;} 46 | 47 | int a[16384], b[16384]; 48 | main() { 49 | RangeOp r(16384,plus); 50 | int i, j, k, x, y, z, nz; 51 | for( i = 0; i < 16384; i++ ) {a[i] = i; b[i] = -1;} 52 | r.set(0, a, a+16384); 53 | for(;;) { 54 | x = rand()%100; 55 | if( x>20 ) { 56 | x = rand()%16384; 57 | y = rand()%16384 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | template struct RangeOp { 8 | Op op; 9 | T *t, c[32], def; 10 | int s, cs[32], ce[32], cv; 11 | 12 | RangeOp(int n, T def=T(), Op op=Op()) : cv(0), def(def), op(op) { 13 | for (s=1; s>1, b=(ce[d]=b)>>1; 23 | if ((cs[d]=a)==(ce[d]=b)) c[d]=def; 24 | if (cvq?c[d]:op(c[d],t[b++])); 28 | } 29 | return c[0]; 30 | } 31 | 32 | // optional: for setting a range of values at once 33 | template void set(int p, it i, it j) { 34 | int q=p+=s; 35 | for (; i!=j; ++i) t[q++]=*i; 36 | for (cv=0; q=q+1>>1,p>>=1;) 37 | for (int k=p; k>=1;) 45 | if ((v=op(t[p*2],t[p*2+1]))==t[p]) break; 46 | } 47 | }; 48 | 49 | RangeOp > r(8000); 50 | RangeOp > r2(1000, 1); 51 | int min(const int &a, const int &b) {return min(a,b);} 52 | RangeOp r3(1000, 2147483647, min); 53 | 54 | int a[16384], b[16384]; 55 | main() { 56 | RangeOp > r(16384); 57 | int i, j, k, x, y, z, nz; 58 | for( i = 0; i < 16384; i++ ) {a[i] = i; b[i] = -1;} 59 | r.set(0, a, a+16384); 60 | for(;;) { 61 | x = rand()%100; 62 | if( x>20 ) { 63 | x = rand()%16384; 64 | y = rand()%16384 bipartitematch(const vector > &m, int nm) { 3 | vector mat(nm, -1), ret(m.size(), -1); 4 | int i, j, x, y; 5 | 6 | for( i = 0; i < m.size(); i++ ) { 7 | queue q; 8 | vector pred(m.size(), -1); 9 | q.push(i); 10 | pred[i] = -2; 11 | while( !q.empty() ) { 12 | x = q.front(); q.pop(); 13 | for( j = 0; j < m[x].size(); j++ ) { 14 | y = mat[m[x][j]]; 15 | if( y == -1 ) goto found; 16 | if( pred[y] != -1 ) continue; 17 | pred[y] = x; 18 | q.push(y); 19 | } 20 | } 21 | continue; 22 | found: y = m[x][j]; 23 | while( x != -2 ) { 24 | mat[y] = x; 25 | swap(ret[x], y); 26 | x = pred[x]; 27 | } 28 | } 29 | return ret; 30 | } 31 | -------------------------------------------------------------------------------- /old/tokenize.cc: -------------------------------------------------------------------------------- 1 | vector tokenize(string s, string ch) { 2 | vector ret; 3 | for( int p = 0, p2; p < s.size(); p = p2+1 ) { 4 | p2 = s.find_first_of(ch, p); 5 | if( p2 == -1 ) p2 = s.size(); 6 | if( p2-p > 0 ) ret.push_back( s.substr(p, p2-p) ); 7 | } 8 | return ret; 9 | } 10 | 11 | vector tokint(string s, string ch) { 12 | vector ret; 13 | vector p = tokenize(s, ch); 14 | for( int i = 0; i < p.size(); i++ ) 15 | ret.push_back( atoi(p[i].c_str()) ); 16 | return ret; 17 | } 18 | 19 | vector > tokmat(vector s, string ch) { 20 | vector > ret; 21 | for( int i = 0; i < s.size(); i++ ) 22 | ret.push_back( tokint(s[i], ch) ); 23 | return ret; 24 | } 25 | -------------------------------------------------------------------------------- /old/unionfind.cc: -------------------------------------------------------------------------------- 1 | template class UnionFind { 2 | map comp; 3 | 4 | public: 5 | T dofind(const T &x) { 6 | map::iterator it = comp.find(x); 7 | if( it == comp.end() ) return comp[x]=x; 8 | T &ret = it->second; 9 | if( ret == x ) return ret; 10 | return ret=dofind(ret); 11 | } 12 | 13 | // if we always call with x < y, this guarantees the representative is 14 | // always the least element 15 | void dounion(const T &x, const T &y) { 16 | comp[dofind(y)] = dofind(x); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /parsing.h: -------------------------------------------------------------------------------- 1 | #ifndef __PARSING_H 2 | #define __PARSING_H 3 | 4 | //// Parsing functions. Formatted for process.exe. 5 | 6 | //// *** Tokenizing strings *** 7 | 8 | vector Tokenize(string s, string ch) { 9 | vector ret; 10 | for (int p = 0, p2; p < s.size(); p = p2+1) { 11 | p2 = s.find_first_of(ch, p); 12 | if (p2 == -1) p2 = s.size(); 13 | if (p2-p > 0) ret.push_back(s.substr(p, p2-p)); 14 | } 15 | return ret; 16 | } 17 | 18 | vector TokenizeInt(string s, string ch) { 19 | vector ret; 20 | vector p = Tokenize(s, ch); 21 | for( int i = 0; i < p.size(); i++ ) 22 | ret.push_back(atoi(p[i].c_str())); 23 | return ret; 24 | } 25 | 26 | vector TokenizeLL(string s, string ch) { 27 | vector ret; 28 | vector p = Tokenize(s, ch); 29 | for( int i = 0; i < p.size(); i++ ) 30 | ret.push_back(StringToLL(p[i])); 31 | return ret; 32 | } 33 | 34 | vector > TokenizeMatrix(vector s, string ch) { 35 | vector > ret; 36 | for( int i = 0; i < s.size(); i++ ) 37 | ret.push_back( TokenizeInt(s[i], ch) ); 38 | return ret; 39 | } 40 | 41 | //// *** Transformation to/from string representation *** 42 | 43 | long long StringToLL(string s) { 44 | istringstream sin(s); 45 | long long ret; 46 | sin >> ret; 47 | return ret; 48 | } 49 | 50 | template string ToString(T a) { 51 | ostringstream sout; 52 | sout << a; 53 | return sout.str(); 54 | } 55 | 56 | string VCToString(const VC &a) {return string(a.begin(), a.end());} 57 | 58 | VC StringToVC(const string &s) {return VC(s.begin(), s.end());} 59 | 60 | template string VectorToString(vector v, char delim = ' ') { 61 | ostringstream sout; 62 | for (int i = 0; i < v.size(); i++) { 63 | if (i) sout << delim; 64 | sout << v[i]; 65 | } 66 | return sout.str(); 67 | } 68 | 69 | template string ArrayToString(const T* ar, int n, char delim=' ') { 70 | ostringstream sout; 71 | for (int i = 0; i < n; i++) { 72 | if (i) sout << delim; 73 | sout << ar[i]; 74 | } 75 | return sout.str(); 76 | } 77 | 78 | //// *** Hashing *** 79 | 80 | struct HashString {int operator()(const string &s) const {return hash()(s.c_str());}}; 81 | 82 | #endif // __PARSING_H 83 | -------------------------------------------------------------------------------- /process.cc: -------------------------------------------------------------------------------- 1 | // A program that reads in a C++ file intended for a TopCoder problem, and 2 | // substitutes in any required #includes and referenced library code. 3 | // 4 | // Makes the assumption that the code looks like this: 5 | // (header comments and stuff) 6 | // (#include) 7 | // (#include) 8 | // ... 9 | // (#include) 10 | // using namespace std; 11 | // 12 | // (function/struct/class/typedef/#define block or blank line) 13 | // (declaration) 14 | // ... 15 | // (declaration) 16 | // 17 | // Declaration blocks consist of: 18 | // [possible non-function lines, comments, globals, etc.] 19 | // foo func(...) { 20 | // } 21 | // [possible blank line, except after typedefs/#defines] 22 | // This helps preserve blank lines as intended in the original file. 23 | // Other miscellaneous blocks are possible, demarcated by blank lines. They 24 | // will be preserved. 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | using namespace std; 35 | 36 | string USINGSTR = "using namespace std;"; 37 | 38 | char buf[10000]; 39 | vector inlines, outlines; 40 | 41 | void throw_error(int errnum, const string& err) { 42 | cerr << err << endl; 43 | for (int i = 0; i < inlines.size(); i++) cout << inlines[i] << endl; 44 | exit(errnum); 45 | } 46 | 47 | 48 | // Strips trailing spaces from a string. 49 | string strip_trailing_spaces(const string &s) { 50 | int i; 51 | for (i = s.size()-1; i >= 0 && isspace(s[i]); i--) 52 | ; 53 | return s.substr(0, i+1); 54 | } 55 | 56 | // Recognizes a C++ identifier character. 57 | inline bool is_ident_char(char ch) { 58 | return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || 59 | (ch >= '0' && ch <= '9') || ch == '_'; 60 | } 61 | 62 | 63 | // Increments to the next character on the same line. Properly follows 64 | // backslashes to the next line. 65 | inline void next_char_on_line(const vector& lines, int& line, int& i) { 66 | i++; 67 | if (i+1 == lines[line].size() && lines[line][i] == '\\' && 68 | line+1 < lines.size()) { 69 | line++; 70 | i = 0; 71 | } 72 | } 73 | 74 | // Increments to the next valid character, possibly on a subsequent line. 75 | // Skips blank lines. 76 | // Postcondition: line == lines.size() || lines[line][i] is valid. 77 | inline void next_char(const vector& lines, int& line, int& i) { 78 | if (++i >= lines[line].size()) { 79 | i = 0; 80 | do {line++;} while (line < lines.size() && !lines[line].size()); 81 | } 82 | } 83 | 84 | // If we're on a comment or #PRAGMA, skip over it. 85 | inline bool skip_comment(const vector& lines, int& line, int& i) { 86 | if (line == lines.size()) return false; 87 | if (i+1 < lines[line].size() && lines[line][i] == '/') { 88 | if (lines[line][i+1] == '/') { 89 | while (i < lines[line].size()) next_char_on_line(lines, line, i); 90 | next_char(lines, line, i); 91 | return true; 92 | } else if (lines[line][i+1] == '*') { 93 | i += 2; 94 | do { 95 | next_char(lines, line, i); 96 | if (line == lines.size()) { 97 | throw_error(1, "// PROCESS ERROR: Unclosed comment."); 98 | } 99 | } while (!(i && lines[line][i-1] == '*' && lines[line][i] == '/')); 100 | next_char(lines, line, i); 101 | return true; 102 | } 103 | } 104 | return false; 105 | } 106 | 107 | // If we're on a string, skip over it. 108 | inline bool skip_string(const vector& lines, int& line, int& i) { 109 | if (line < lines.size() && i < lines[line].size() && 110 | (lines[line][i] == '"' || lines[line][i] == '\'')) { 111 | char ch = lines[line][i]; 112 | do { 113 | next_char_on_line(lines, line, i); 114 | if (i && i < lines[line].size() && lines[line][i-1] == '\\') { 115 | next_char_on_line(lines, line, i); 116 | } 117 | if (i == lines[line].size()) { 118 | throw_error(1, "// PROCESS ERROR: Unclosed string."); 119 | } 120 | } while (lines[line][i] != ch); 121 | next_char(lines, line, i); 122 | return true; 123 | } 124 | return false; 125 | } 126 | 127 | // Increments until it finds the matching bracket, parenthesis, etc. Skips 128 | // comments/strings and handles nesting properly. 129 | void match_bracket(const vector& lines, char open, char close, 130 | int& line, int& i) { 131 | assert(lines[line][i] == open); 132 | int v = 0; 133 | for (;;) { 134 | v += (lines[line][i] == open) - (lines[line][i] == close); 135 | if (!v) return; 136 | next_char(lines, line, i); 137 | while (skip_comment(lines, line, i) || skip_string(lines, line, i)) 138 | ; 139 | if (line == lines.size()) { 140 | throw_error(1, "// PROCESS ERROR: Unclosed bracket."); 141 | } 142 | } 143 | } 144 | 145 | // Increments "line" and "i" until it finds a semicolon that is in the current 146 | // scope (ie, outside any {} or () brackets). 147 | void find_semicolon(const vector& lines, int& line, int& i) { 148 | for (;;) { 149 | while (skip_comment(lines, line, i) || skip_string(lines, line, i)) 150 | ; 151 | if (line < lines.size() && lines[line][i] == '(') { 152 | match_bracket(lines, '(', ')', line, i); 153 | } 154 | if (line < lines.size() && lines[line][i] == '{') { 155 | match_bracket(lines, '{', '}', line, i); 156 | } 157 | if (line == lines.size()) { 158 | throw_error(1, "// PROCESS ERROR: Missing semicolon."); 159 | } 160 | if (lines[line][i] == ';') return; 161 | next_char(lines, line, i); 162 | } 163 | } 164 | 165 | // Returns (and skips over) the keyword at the current character. 166 | // A keyword is a C++ identifier, possibly followed by a '(' or '<'. 167 | string keyword(const vector& lines, int& line, int& i) { 168 | string ret = ""; 169 | if (line == lines.size() || i == lines[line].size()) return ret; 170 | if (!is_ident_char(lines[line][i])) return ret; 171 | 172 | int startline = line; 173 | for (;;) { 174 | ret += lines[line][i]; 175 | next_char(lines, line, i); 176 | if (line > startline) { 177 | return ret; 178 | } 179 | if (lines[line][i] == '(' || lines[line][i] == '<') { 180 | return ret + lines[line][i]; 181 | } 182 | if (!is_ident_char(lines[line][i])) { 183 | return ret; 184 | } 185 | } 186 | } 187 | 188 | 189 | // A map of keywords that force various #includes to be added. 190 | map include_map; 191 | void initialize_include_map(const char *include_filename) { 192 | ifstream fin(include_filename); 193 | if (!fin.good()) { 194 | throw_error(3, string("// PROCESS ERROR: Could not read file \"") + 195 | include_filename + "\"."); 196 | } 197 | string s, include; 198 | while (fin >> s) { 199 | if (s == "#include") { 200 | fin >> include; 201 | include = "#include " + include; 202 | } else { 203 | include_map[s] = include; 204 | } 205 | } 206 | } 207 | 208 | // Reads a complete declaration and associates a keyword with it. (The keyword 209 | // may be empty if the declaration is an unrecognized type.) 210 | pair > parse_declaration( 211 | const vector &lines, int &line) { 212 | int startline = line, i = 0; 213 | pair > ret; 214 | bool saw_template = false; 215 | 216 | if (lines[line].size() == 0) { 217 | line++; 218 | return make_pair("", vector(1, "")); 219 | } 220 | 221 | for (;;) { 222 | while (skip_comment(lines, line, i) || skip_string(lines, line, i)) 223 | ; 224 | 225 | if (line == lines.size()) { 226 | break; 227 | } 228 | if (line > startline && lines[line-1].size() == 0) { 229 | int j; 230 | for (j = i-1; j >= 0 && isspace(lines[line][j]); j--) 231 | ; 232 | if (j < 0) { 233 | // We just passed a blank line, ending a miscellaneous block. 234 | while (line > startline && lines[line-1].size() == 0) { 235 | line--; 236 | } 237 | break; 238 | } 239 | } 240 | 241 | if (line < lines.size() && lines[line][i] == '{') { 242 | match_bracket(lines, '{', '}', line, i); 243 | } 244 | if (line < lines.size() && lines[line][i] == '(') { 245 | match_bracket(lines, '(', ')', line, i); 246 | } 247 | 248 | if (i == 0 && (lines[line].substr(0, 9) == "#include " || 249 | lines[line] == USINGSTR)) { 250 | // #includes are a block to themselves, and do not include previous lines. 251 | if (line > startline) break; 252 | ret.first = lines[line]; 253 | if (lines[line] == USINGSTR && line+1 < lines.size() && 254 | lines[line+1].size() == 0) { 255 | // Include blank line after USINGSTR. 256 | line++; 257 | } 258 | line++; i = 0; 259 | break; 260 | } 261 | 262 | if (i == 0 && lines[line].substr(0, 8) == "#define ") { 263 | // #define statement; keyword is next on line. 264 | for (i = 8; i < lines[line].size() && !is_ident_char(lines[line][i]); i++) 265 | ; 266 | for (; i < lines[line].size() && is_ident_char(lines[line][i]); i++) 267 | ret.first += lines[line][i]; 268 | if (ret.first == "") { 269 | throw_error(1, "// PROCESS ERROR: Could not parse #define."); 270 | } 271 | if (i == lines[line].size()) { 272 | // Empty defines are probably for include files and can be ignored. 273 | ret.first = ""; 274 | } 275 | if (i < lines[line].size() && lines[line][i] == '(') { 276 | ret.first += lines[line][i]; 277 | } 278 | while (i < lines[line].size()) next_char_on_line(lines, line, i); 279 | line++; i = 0; 280 | break; 281 | } 282 | 283 | string kw = keyword(lines, line, i); 284 | if (kw == "typedef") { 285 | // typedef statement; keyword is last on line. 286 | find_semicolon(lines, line, i); 287 | for (i--; i >= 0 && is_ident_char(lines[line][i]); i--) { 288 | ret.first += lines[line][i]; 289 | } 290 | if (ret.first == "") { 291 | throw_error(1, "// PROCESS ERROR: Could not parse typedef."); 292 | } 293 | reverse(ret.first.begin(), ret.first.end()); 294 | line++; i = 0; 295 | break; 296 | } 297 | 298 | if (kw == "template<") { 299 | saw_template = true; 300 | match_bracket(lines, '<', '>', line, i); 301 | } 302 | 303 | if (kw == "struct" || kw == "class" || 304 | (kw.size() >= 2 && kw[kw.size()-1] == '(')) { 305 | bool func = (kw[kw.size()-1] == '('); 306 | if (!func) { 307 | // struct/class declaration; actual keyword is next. 308 | for (;;) { 309 | while (skip_comment(lines, line, i) || skip_string(lines, line, i)) 310 | ; 311 | if (line == lines.size() || 312 | (lines[line][i] != ' ' && !is_ident_char(lines[line][i]))) { 313 | throw_error(1, "// PROCESS ERROR: Could not parse struct def."); 314 | } 315 | kw = keyword(lines, line, i); 316 | if (kw != "") break; 317 | next_char(lines, line, i); 318 | } 319 | } 320 | 321 | // Find a '{' to make sure this isn't just a forward declaration. 322 | for (;;) { 323 | while (skip_comment(lines, line, i) || skip_string(lines, line, i)) 324 | ; 325 | if (line == lines.size()) { 326 | throw_error(1, "// PROCESS ERROR: Could not parse func/struct def."); 327 | } 328 | if (lines[line][i] == ';' || lines[line][i] == '{') break; 329 | next_char(lines, line, i); 330 | } 331 | 332 | if (lines[line][i] == '{') { 333 | ret.first = kw; 334 | // Templated structs are invoked using a '<', so be sure to include 335 | // that in the keyword. 336 | if (!func && saw_template) ret.first += '<'; 337 | 338 | match_bracket(lines, '{', '}', line, i); 339 | 340 | // Include a possible trailing blank line. 341 | line++; i = 0; 342 | if (line < lines.size() && lines[line].size() == 0) { 343 | line++; 344 | } 345 | break; 346 | } 347 | } 348 | 349 | if (kw == "") next_char(lines, line, i); 350 | } 351 | 352 | ret.second = vector(lines.begin()+startline, lines.begin()+line); 353 | return ret; 354 | } 355 | 356 | // Parse all declarations from a library file. 357 | map > declaration_map; 358 | void read_library_file(const char *library_filename) { 359 | ifstream fin(library_filename); 360 | if (!fin.good()) { 361 | throw_error(3, string("// PROCESS ERROR: Could not read file \"") + 362 | library_filename + "\"."); 363 | } 364 | vector lines; 365 | while (fin.getline(buf, 10000)) 366 | if (buf[0] != '/' || buf[1] != '/' || buf[2] != '/' || buf[3] != '/') 367 | lines.push_back(strip_trailing_spaces(buf)); 368 | for (int line = 0; line < lines.size();) { 369 | // Precede declarations with a blank line, EXCEPT between #define and 370 | // typedefs. 371 | pair > dec = parse_declaration(lines, line); 372 | if (dec.first.size()) declaration_map[dec.first] = dec.second; 373 | } 374 | } 375 | 376 | bool is_simple_typedef(const pair >& decl) { 377 | return decl.second.size() == 1 && decl.second[0].substr(0, 8) == "typedef " && 378 | decl.second[0].find('<') == -1; 379 | } 380 | bool is_simple_define(const pair >& decl) { 381 | return decl.second[0].substr(0, 8) == "#define "; 382 | } 383 | 384 | vector process(const vector &lines) { 385 | // First parse the #include block at the top of the file. 386 | vector > > includes; 387 | int line = 0; 388 | int first_include = -1; 389 | while (line < lines.size()) { 390 | includes.push_back(parse_declaration(lines, line)); 391 | if (includes.back().first.substr(0, 9) == "#include ") { 392 | if (first_include == -1) first_include = includes.size()-1; 393 | } else if (includes.back().first == USINGSTR) { 394 | if (first_include == -1) first_include = includes.size()-1; 395 | break; 396 | } else if (first_include != -1) { 397 | throw_error(2, string("// PROCESS ERROR: Missing \"") + USINGSTR + "\"."); 398 | } 399 | } 400 | if (first_include != -1 && includes.back().first != USINGSTR) { 401 | throw_error(2, string("// PROCESS ERROR: Missing \"") + USINGSTR + "\"."); 402 | } 403 | 404 | if (first_include == -1) { 405 | // There was no #include block at all. Make one. 406 | includes.clear(); 407 | includes.push_back(make_pair(USINGSTR, vector(1, USINGSTR))); 408 | includes.back().second.push_back(""); 409 | first_include = 0; 410 | line = 0; 411 | } 412 | 413 | // Run through the declarations in order, parsing for keywords and adding any 414 | // new includes or declarations as needed. 415 | vector > > declarations; 416 | while (line < lines.size()) { 417 | declarations.push_back(parse_declaration(lines, line)); 418 | } 419 | 420 | restart_scan: 421 | int first_typedef = -1, last_typedef = -1; 422 | int first_define = -1, last_define = -1; 423 | for (int i = 0; i < declarations.size(); i++) { 424 | // Try to keep simple typedefs and defines together. 425 | if (is_simple_typedef(declarations[i])) { 426 | if (first_typedef == -1) first_typedef = i; 427 | } else { 428 | if (first_typedef != -1 && last_typedef == -1) last_typedef = i-1; 429 | } 430 | if (is_simple_define(declarations[i])) { 431 | if (first_define == -1) first_define = i; 432 | } else { 433 | if (first_define != -1 && last_define == -1) last_define = i-1; 434 | } 435 | 436 | // Scan for keywords. 437 | const vector& ds = declarations[i].second; 438 | int dline = 0, di = 0; 439 | for (;;) { 440 | while (skip_comment(ds, dline, di) || skip_string(ds, dline, di)) 441 | ; 442 | if (dline == ds.size()) break; 443 | string kw = keyword(ds, dline, di); 444 | if (kw == "") { 445 | next_char(ds, dline, di); 446 | } else { 447 | // We have a keyword; check for includes or declarations. 448 | if (include_map.count(kw)) { 449 | pair > decl(include_map[kw], 450 | vector(1, include_map[kw])); 451 | int d; 452 | for (d = 0; d < includes.size(); d++) { 453 | if (includes[d] == decl) break; 454 | } 455 | if (d == includes.size()) { 456 | includes.push_back(decl); 457 | } 458 | } 459 | if (declaration_map.count(kw)) { 460 | // Make sure there's not already a declaration by this name. 461 | int d; 462 | for (d = 0; d < declarations.size(); d++) { 463 | if (declarations[d].first == kw) break; 464 | } 465 | if (d == declarations.size()) { 466 | pair > decl(kw, 467 | declaration_map[kw]); 468 | 469 | // Normally we add the library declaration just before the current 470 | // block. However, try to keep simple typedefs/defines together. 471 | int insert_index = i; 472 | if (is_simple_typedef(decl)) { 473 | if (first_typedef == -1) { 474 | insert_index = 0; 475 | declarations.insert(declarations.begin() + insert_index, 476 | make_pair("", vector(1, ""))); 477 | } else if (last_typedef != -1) { 478 | insert_index = last_typedef + 1; 479 | } 480 | } 481 | if (is_simple_define(decl)) { 482 | if (first_define == -1) { 483 | insert_index = 0; 484 | if (last_typedef != -1) { 485 | insert_index = last_typedef + 1; 486 | if (insert_index < declarations.size() && 487 | declarations[insert_index].second == 488 | vector(1, "")) { 489 | insert_index++; 490 | } 491 | } 492 | declarations.insert(declarations.begin() + insert_index, 493 | make_pair("", vector(1, ""))); 494 | } else if (last_define != -1) { 495 | insert_index = last_define + 1; 496 | } 497 | } 498 | 499 | declarations.insert(declarations.begin() + insert_index, decl); 500 | goto restart_scan; 501 | } 502 | } 503 | } 504 | } 505 | } 506 | 507 | // Keep includes in sorted order. 508 | sort(includes.begin()+first_include, includes.end()); 509 | includes.erase(unique(includes.begin()+first_include, includes.end()), 510 | includes.end()); 511 | 512 | // Put together the final source file. 513 | vector ret; 514 | for (int i = 0; i < includes.size(); i++) { 515 | ret.insert(ret.end(), includes[i].second.begin(), 516 | includes[i].second.end()); 517 | } 518 | for (int i = 0; i < declarations.size(); i++) { 519 | ret.insert(ret.end(), declarations[i].second.begin(), 520 | declarations[i].second.end()); 521 | } 522 | return ret; 523 | } 524 | 525 | int main(int argc, char* argv[]) { 526 | if (argc != 3) { 527 | cerr << "Usage: " << argv[0] 528 | << " (includes file) (library file)" << endl; 529 | return 0; 530 | } 531 | 532 | // Read input source file. 533 | while (cin.getline(buf, 10000)) 534 | inlines.push_back(strip_trailing_spaces(buf)); 535 | 536 | initialize_include_map(argv[1]); 537 | ifstream fin(argv[2]); 538 | if (!fin.good()) { 539 | throw_error(3, string("// PROCESS ERROR: Could not read file \"") + 540 | argv[2] + "\"."); 541 | } 542 | string fname; 543 | while (getline(fin, fname)) read_library_file(fname.c_str()); 544 | 545 | outlines = process(inlines); 546 | for (int i = 0; i < outlines.size(); i++) cout << outlines[i] << '\n'; 547 | 548 | return 0; 549 | } 550 | --------------------------------------------------------------------------------