博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF1093G Multidimensional Queries
阅读量:4700 次
发布时间:2019-06-09

本文共 3445 字,大约阅读时间需要 11 分钟。

思路:

参考了。主要利用了曼哈顿距离的性质。

实现过程中遇到一个问题:不同的线段树数组的定义方式会导致运行速度很大的差别。tree[800000][32][2]比tree[2][32][800000]快了一倍,从而导致了TLE和AC的区别。可能是程序运行过程中频繁访问不连续的地址导致cache失效。以后如果需要对很大的数组进行频繁操作的话需要注意这一点。

实现:

1 #include 
2 using namespace std; 3 const int N = 200005, K = 5, INF = 0x3f3f3f3f; 4 int a[N][K], b[K], tree[N * 4][1 << K][2], n, k; 5 6 void build(int num, int l, int r) 7 { 8 if (l == r) 9 { 10 for (int i = 0; i < (1 << k); i++) 11 { 12 int sum = 0; 13 for (int d = 0; d < k; d++) 14 { 15 if ((i >> d) & 1) sum += a[l][d]; 16 else sum -= a[l][d]; 17 } 18 tree[num][i][0] = tree[num][i][1] = sum; 19 } 20 return; 21 } 22 int m = l + r >> 1; 23 build(num << 1, l, m); 24 build(num << 1 | 1, m + 1, r); 25 for (int i = 0; i < (1 << k); i++) 26 { 27 tree[num][i][1] = max(tree[num << 1][i][1], tree[num << 1 | 1][i][1]); 28 tree[num][i][0] = min(tree[num << 1][i][0], tree[num << 1 | 1][i][0]); 29 } 30 } 31 32 void update(int num, int l, int r, int x) 33 { 34 if (l == r) 35 { 36 for (int i = 0; i < (1 << k); i++) 37 { 38 int sum = 0; 39 for (int d = 0; d < k; d++) 40 { 41 if ((i >> d) & 1) sum += b[d]; 42 else sum -= b[d]; 43 } 44 tree[num][i][0] = tree[num][i][1] = sum; 45 } 46 return; 47 } 48 int m = l + r >> 1; 49 if (x <= m) update(num << 1, l, m, x); 50 else update(num << 1 | 1, m + 1, r, x); 51 for (int i = 0; i < (1 << k); i++) 52 { 53 tree[num][i][1] = max(tree[num << 1][i][1], tree[num << 1 | 1][i][1]); 54 tree[num][i][0] = min(tree[num << 1][i][0], tree[num << 1 | 1][i][0]); 55 } 56 } 57 58 int query(int num, int l, int r, int x, int y, int t, int id) 59 { 60 if (x <= l && y >= r) return tree[num][id][t]; 61 if (y < l || x > r) return t ? -INF : INF; 62 int m = l + r >> 1, ans = t ? -INF : INF; 63 if (x <= m) 64 { 65 if (t) ans = max(ans, query(num << 1, l, m, x, y, t, id)); 66 else ans = min(ans, query(num << 1, l, m, x, y, t, id)); 67 } 68 if (y >= m + 1) 69 { 70 if (t) ans = max(ans, query(num << 1 | 1, m + 1, r, x, y, t, id)); 71 else ans = min(ans, query(num << 1 | 1, m + 1, r, x, y, t, id)); 72 } 73 return ans; 74 } 75 76 int main() 77 { 78 int q, t, x, l, r; 79 scanf("%d %d", &n, &k); 80 for (int i = 1; i <= n; i++) 81 for (int j = 0; j < k; j++) 82 scanf("%d", &a[i][j]); 83 build(1, 1, n); 84 scanf("%d", &q); 85 while (q--) 86 { 87 scanf("%d", &t); 88 if (t == 1) 89 { 90 scanf("%d", &x); 91 for (int i = 0; i < k; i++) scanf("%d", &b[i]); 92 update(1, 1, n, x); 93 } 94 else 95 { 96 scanf("%d %d", &l, &r); 97 int ans = -INF; 98 for (int i = 0; i < (1 << k); i++) 99 {100 int maxn = query(1, 1, n, l, r, 1, i);101 int minn = query(1, 1, n, l, r, 0, i);102 ans = max(ans, maxn - minn);103 }104 printf("%d\n", ans);105 }106 }107 return 0;108 }

 

转载于:https://www.cnblogs.com/wangyiming/p/11039156.html

你可能感兴趣的文章
找不到请求的 .Net Framework Data Provider。可能没有安装
查看>>
实验室管理系统(SQL+VS)
查看>>
C# protogen 处理protobuf生成cs文件
查看>>
oracle_SQL 实验查询及删除重复记录 依据条件 (row)
查看>>
SSM框架搭建
查看>>
[UE4]蓝图比C++慢10倍,是吗?
查看>>
使用IdleTest进行TDD单元测试驱动开发演练(1)
查看>>
零基础入门深度学习(2) - 线性单元和梯度下降
查看>>
微软职位内部推荐-Senior SDE
查看>>
守护进程
查看>>
初入linux系统
查看>>
机器学习预测机动车摇号:神秘的第七位
查看>>
linux 下启动tomcat 提示-bash: ./startup.sh: Permission denied 原来...
查看>>
洛谷P1041 传染病控制
查看>>
Android:interpolator用法
查看>>
集合和函数
查看>>
thinkPHP5 验证码
查看>>
『摄影欣赏』25幅记录欢乐瞬间的精美照片【组图】
查看>>
一款效果精致的 jQuery 多层滑出菜单插件
查看>>
推荐10个 CSS3 制作的创意下拉菜单效果
查看>>