这个题是真正可以体现出块状链表的优点。数组定位快但是插入慢,而链表插入快却定位慢。块状链表正是结合了数组和链表的优点将定位和插入的复杂度变成了sqrt(n)。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 750; 7 int b[N][N]; 8 int sz[N]; 9 int next[N]; 10 int ps; 11 int bl; 12 13 void init() 14 { 15 bl = 1; 16 ps = 550; 17 memset( sz, 0, sizeof(sz) ); 18 memset( next, -1, sizeof(next) ); 19 } 20 21 void spilt( int cur ) 22 { 23 int tmp = next[cur]; 24 int ncur = next[cur] = bl++; 25 next[ncur] = tmp; 26 for ( int i = sz[cur] / 2; i < sz[cur]; i++ ) 27 { 28 b[ncur][sz[ncur]++] = b[cur][i]; 29 } 30 sz[cur] = sz[cur] / 2; 31 } 32 33 void insert( int pos, int val ) 34 { 35 int cur = 0, p = sz[cur]; 36 while ( p < pos + 1 && next[cur] != -1 ) 37 { 38 cur = next[cur]; 39 p += sz[cur]; 40 } 41 if ( p < pos + 1 ) 42 { 43 b[cur][sz[cur]++] = val; 44 } 45 else 46 { 47 p -= sz[cur]; 48 pos -= p; 49 for ( int j = sz[cur] - 1; j >= pos; j-- ) 50 { 51 b[cur][j + 1] = b[cur][j]; 52 } 53 b[cur][pos] = val; 54 sz[cur]++; 55 } 56 if ( sz[cur] > ps ) spilt(cur); 57 } 58 59 int main () 60 { 61 int n; 62 while ( scanf("%d", &n) != EOF ) 63 { 64 init(); 65 for ( int i = 0; i < n; i++ ) 66 { 67 int pos, val; 68 scanf("%d%d", &pos, &val); 69 insert( pos, val ); 70 } 71 int cnt = 0; 72 for ( int i = 0; i != -1; i = next[i] ) 73 { 74 for ( int j = 0; j < sz[i]; j++ ) 75 { 76 printf("%d", b[i][j]); 77 cnt++; 78 if ( cnt != n ) 79 { 80 putchar(‘ ‘); 81 } 82 else 83 { 84 putchar(‘\n‘); 85 } 86 } 87 } 88 } 89 return 0; 90 }
时间: 2024-10-20 05:28:41