poj 2887 块状链表

块状链表第一题,懒得写成链表形式的,所以写成了静态链表。

思想还是很简单的,就是进行分块查找和插入,和建立索引有点像,复杂度是根号的,实现起来比较容易,由于这个题插入操作不多,所以没有写split函数,

因为没有删除操作,所以也没有写union函数,随后有空再补上吧。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <cmath>
  5 using namespace std;
  6
  7 const int N = 1002001;
  8 const int M = 2000;
  9 char str[N];
 10
 11 struct Block
 12 {
 13     char ch[M];
 14     int size;
 15     int next;
 16
 17     void init()
 18     {
 19         size = 0;
 20         next = -1;
 21     }
 22
 23 };
 24
 25 struct BlockList
 26 {
 27     int head, len;
 28     Block b[M];
 29
 30     void init( char * s )
 31     {
 32         len = strlen(s);
 33         int as = sqrt( ( double ) len );
 34         head = 0;
 35         int j = head;
 36         b[j].init();
 37         for ( int i = 0; i < len; i++ )
 38         {
 39             if ( b[j].size == as )
 40             {
 41                 b[j].next = j + 1;
 42                 j++;
 43                 b[j].init();
 44             }
 45             b[j].ch[b[j].size++] = s[i];
 46         }
 47     }
 48
 49     //插在第pos个元素前面
 50     void insert( int pos, char v )
 51     {
 52         if ( pos > len )
 53         {
 54             int i = head, j = b[head].next;
 55             while ( j != -1 )
 56             {
 57                 i = b[i].next;
 58                 j = b[j].next;
 59             }
 60             b[i].ch[b[i].size++] = v;
 61             len++;
 62             return ;
 63         }
 64         int i = head;
 65         while ( pos > b[i].size )
 66         {
 67             pos -= b[i].size;
 68             i = b[i].next;
 69         }
 70         for ( int j = b[i].size; j >= pos; j-- )
 71         {
 72             b[i].ch[j] = b[i].ch[j - 1];
 73         }
 74         b[i].ch[pos - 1] = v;
 75         b[i].size++;
 76         len++;
 77         return ;
 78     }
 79
 80     char at( int pos )
 81     {
 82         int i = head;
 83         while ( pos > b[i].size )
 84         {
 85             pos -= b[i].size;
 86             i = b[i].next;
 87         }
 88         return b[i].ch[pos - 1];
 89     }
 90
 91 } bl;
 92
 93 int main()
 94 {
 95     while ( scanf("%s", str) != EOF )
 96     {
 97         bl.init(str);
 98         int n;
 99         char op[2];
100         scanf("%d", &n);
101         while ( n-- )
102         {
103             scanf("%s", op);
104             if ( op[0] == ‘I‘ )
105             {
106                 char ch[2];
107                 int p;
108                 scanf("%s%d", ch, &p);
109                 bl.insert( p, ch[0] );
110             }
111             else
112             {
113                 int p;
114                 scanf("%d", &p);
115                 char ans = bl.at(p);
116                 printf("%c\n", ans);
117             }
118         }
119     }
120     return 0;
121 }
时间: 2024-10-20 22:33:03

poj 2887 块状链表的相关文章

poj 2828 块状链表

这个题是真正可以体现出块状链表的优点.数组定位快但是插入慢,而链表插入快却定位慢.块状链表正是结合了数组和链表的优点将定位和插入的复杂度变成了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 in

poj 3468 块状链表 区间修改+区间查询

经典的线段树题目,也可以用块链来做. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cmath> 5 using namespace std; 6 7 typedef __int64 ll; 8 const ll M = 400; 9 ll b[M][M]; 10 ll add[M]; 11 ll sum[M]; 12 ll n, m, ps; 13 14

POJ 2887 Big String (块状数组)

题意:给一个字符串(<=1000000)和n个操作(<2000),每个操作可以在某个位置插入一个字符,或者查询该位置的字符.问查询结果. 思路:块状数组. 如果将原来的字符串都存在一起,每次插入肯定会超时. 而操作数比较少,考虑使用分块法.假设原字符串长度为L,则取每块长度l=sqrt(L).这样每次插入,我们需要用sqrt(L)的时间找到对应的块,再用sqrt(L)在该块进行插入.查询同样需要sqrt(L)找到该块,如果用数组实现可以O(1)找到目标元素.(我尝试用stl链表来做,结果超时了

【POJ2887】【块状链表】Big String

Description You are given a string and supposed to do some string manipulations. Input The first line of the input contains the initial string. You can assume that it is non-empty and its length does not exceed 1,000,000. The second line contains the

【BZOJ2741】【块状链表+可持久化trie】FOTILE模拟赛L

Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r. 为了体现在线操作,对于一个询问(x,y): l = min ( ((x+lastans) mod N)+1 , ((y+lastans) mod N)+1 ).r = max ( ((x+lastans) mod N)+1 , ((y+last

c++之路进阶——块状链表(弹飞绵羊)

2333 弹飞绵羊 2010年省队选拔赛湖南 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Description Lostmonkey发明了一种超级反弹装置.为了在绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿一条直线摆放 n个反弹装置,并按从前往后的方式将反弹装置依次编号为 0 到 n-1,对 0≤i≤n-1,为第 i 个反弹装置设定了初始弹力系数 ki,当绵羊落到第 i 个反弹装置上时,它将被往后

c++之路——块状链表(教主的魔法)

F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  gryz2016 Logout 捐赠本站 Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入.输出语句及数据类型及范围,避免无谓的RE出现. 3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 711  Solved: 309[Submit][Stat

hdu 1754 块状链表 单点修改+单点查询

经典的线段树题目,也可以用块状链表做. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cmath> 5 using namespace std; 6 7 const int N = 200000; 8 const int M = 800; 9 int n, m, tot; 10 11 int max( int a, int b ) 12 { 13 retu

【BZOJ1500】【块状链表】SuperMemo

Description Input 输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的表格. Output 对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行. Sample Input 9 8 2 -6 3 5 1 -5 -3 6 3 GET-SUM 5 4 MAX-SUM INSERT 8 3 -5 7 2 DELETE 12