当前位置: 首页 > news >正文

poj 2828 块状链表 OR 线段树 OR 树状数组

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

线段树:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 200001;
 7 int ans[N];
 8 int n;
 9 
10 struct X
11 {
12     int pos, val;
13 } x[N];
14 
15 struct Node 
16 {
17     int l, r, sum;
18 } node[N << 2];
19 
20 void pushup( int i )
21 {
22     node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum;
23 }
24 
25 void build( int i, int l, int r )
26 {
27     node[i].l = l, node[i].r = r, node[i].sum = node[i].r - node[i].l + 1;
28     if ( l == r ) return ;
29     int mid = ( l + r ) >> 1;    
30     build( i << 1, l, mid );
31     build( i << 1 | 1, mid + 1, r );
32 }
33 
34 void update( int i, int pos, int val )
35 {
36     if ( node[i].l == pos && node[i].r == pos )
37     {
38         node[i].sum = val;
39         return ;
40     }
41     int mid = ( node[i].l + node[i].r ) >> 1;
42     if ( pos <= mid )
43     {
44         update( i << 1, pos, val );
45     }
46     else
47     {
48         update( i << 1 | 1, pos, val );
49     }
50     pushup(i);
51 }
52 
53 int query( int i, int v )
54 {
55     if ( node[i].l == node[i].r ) return node[i].l;
56     if ( node[i << 1].sum >= v ) return query( i << 1, v );
57     return query( i << 1 | 1, v - node[i << 1].sum );
58 }
59 
60 int main ()
61 {
62     while ( scanf("%d", &n) != EOF )
63     {
64         for ( int i = 1; i <= n; i++ )
65         {
66             scanf("%d%d", &x[i].pos, &x[i].val);
67             x[i].pos++;
68         }
69         build( 1, 1, n );
70         for ( int i = n; i >= 1; i-- )
71         {
72             int tmp = query( 1, x[i].pos );
73             ans[tmp] = x[i].val;
74             update( 1, tmp, 0 );
75         }    
76         for ( int i = 1; i < n; i++ )
77         {
78             printf("%d ", ans[i]);
79         }    
80         printf("%d\n", ans[n]);
81     }
82     return 0;
83 }

树状数组:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 200001;
 7 int c[N];
 8 int ans[N];
 9 int n;
10 
11 struct X
12 {
13     int pos, val;
14 } x[N];
15 
16 int lb( int i )
17 {
18     return i & -i;
19 }
20 
21 void update( int i, int v )
22 {
23     while ( i <= n )
24     {
25         c[i] += v;
26         i += lb(i);
27     }
28 }
29 
30 int query( int k )
31 {
32     int ans = 0, cnt = 0;
33     for ( int i = 17; i >= 0; i-- )
34     {
35         ans += ( 1 << i );
36         if ( ans >= n || cnt + c[ans] >= k )
37         {
38             ans -= ( 1 << i );
39         }
40         else
41         {
42             cnt += c[ans];
43         }
44     }
45     return ans + 1;
46 }
47 
48 int main ()
49 {
50     while ( scanf("%d", &n) != EOF )
51     {
52         memset( c, 0, sizeof(c) );
53         for ( int i = 1; i <= n; i++ )
54         {
55             scanf("%d%d", &x[i].pos, &x[i].val);
56             x[i].pos++;
57             update( i, 1 );
58         }
59         for ( int i = n; i >= 1; i-- )
60         {
61             int tmp = query( x[i].pos );
62             ans[tmp] = x[i].val;
63             update( tmp, -1 );
64         }    
65         for ( int i = 1; i < n; i++ )
66         {
67             printf("%d ", ans[i]);
68         }    
69         printf("%d\n", ans[n]);
70     }
71     return 0;
72 }

 

转载于:https://www.cnblogs.com/huoxiayu/p/4734465.html

相关文章:

  • Ruby用6行搞定P2P
  • Bootstrap中面板的使用
  • LCA rmq st model
  • 一个有意思的Ruby脚本
  • 如何提醒客户重载父类的指定方法?
  • 将键盘的按键转换成相应的Unicode 值
  • sqlserver 锁表语句分享
  • 产品版本改造中的项目管理
  • 一种人吃蜂蜜火上浇油
  • windows 特殊文件后缀集合
  • 异或+构造 HDOJ 5416 CRB and Tree
  • 使用loader加载swf
  • WIN7 嵌入式系统安装教程 Windows Embedded Standard 2011 安装
  • [CakePHP] 在Controller中使用Helper
  • SVG图像技术摘要
  • C# 免费离线人脸识别 2.0 Demo
  • C++类的相互关联
  • ES6核心特性
  • es6要点
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • java小心机(3)| 浅析finalize()
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • passportjs 源码分析
  • 老板让我十分钟上手nx-admin
  • 爬虫模拟登陆 SegmentFault
  • 排序(1):冒泡排序
  • 区块链共识机制优缺点对比都是什么
  • 学习笔记TF060:图像语音结合,看图说话
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 优化 Vue 项目编译文件大小
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • (1)(1.13) SiK无线电高级配置(五)
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (Java)【深基9.例1】选举学生会
  • (ros//EnvironmentVariables)ros环境变量
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)springboot教学评价 毕业设计 641310
  • (三) diretfbrc详解
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (译)2019年前端性能优化清单 — 下篇
  • (原)本想说脏话,奈何已放下
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .Net 4.0并行库实用性演练
  • .NET Core Web APi类库如何内嵌运行?
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .Net 路由处理厉害了
  • .NET 中创建支持集合初始化器的类型
  • .net流程开发平台的一些难点(1)
  • .net中应用SQL缓存(实例使用)