题目传送门

以二维为例,二维下两点间的曼哈顿距离最大值为\(max(|x_i-x_j| + |y_i-y_j|)\),可以通过枚举坐标符号正负来去掉绝对值。即\(max(x_i-x_j+y_i-y_j,x_i+x_j+y_i-y_j...)\)共16种情况。设\(f[i][t]\)表示第\(i\)个点各维度数值正负状态为\(t\)时的值,假如二维向量\(p[i]=(1,2)\),那么状态\(t\)的范围为\([0,3]\),如果\(t=2\),即二进制表示为\(10\),那么\(p\)向量第一维数值加个负号,第二维数值不变,类似状压过程。对于每个向量处理出\(f\)的值。最终结果即在\([l,r]\)范围内求\(max(f[i][m],f[j][n])(m+n=(1<<k)-1)\),具体用线段树实现。

#include<cstdio>
#include<vector>
#include<algorithm>
#define ls (u << 1)
#define rs (u << 1 | 1)
using namespace std;
const int N = 2e5 + 50; struct Node{
vector<int> val;
Node() { val.resize(35); }
}node[N << 2]; int n, k, q;
int a[N][6]; void Max(const vector<int> &x, const vector<int> &y, vector<int> &z){
for(int i = 0; i < (1 << k); ++i) z[i] = max(x[i], y[i]);
} void Max(const vector<int> &x, vector<int> &y){
for(int i = 0; i < (1 << k); ++i) y[i] = max(x[i], y[i]);
} void build(int u, int l, int r){
if(l == r){
for(int s = 0; s < (1 << k); ++s){
for(int t = 1; t <= k; ++t){
if(s & (1 << (t - 1))) node[u].val[s] += a[l][t];
else node[u].val[s] -= a[l][t];
}
}
return ;
}
int mid = (l + r) >> 1;
if(l <= mid) build(ls, l, mid);
if(r > mid) build(rs, mid + 1, r);
Max(node[ls].val, node[rs].val, node[u].val);
} void modify(int u, int l, int r, int pos){
if(l == r){
for(int i = 0; i < (1 << k); ++i) node[u].val[i] = 0;
for(int s = 0; s < (1 << k); ++s){
for(int t = 1; t <= k; ++t){
if(s & (1 << (t - 1))) node[u].val[s] += a[l][t];
else node[u].val[s] -= a[l][t];
}
}
return ;
}
int mid = (l + r) >> 1;
if(pos <= mid) modify(ls, l, mid, pos);
else modify(rs, mid + 1, r, pos);
Max(node[ls].val, node[rs].val, node[u].val);
} vector<int> ans(35); void query(int u, int l, int r, int ql, int qr){
if(ql <= l && qr >= r){
Max(node[u].val, ans);
return ;
}
int mid = (l + r) >> 1;
if(ql <= mid) query(ls, l, mid, ql, qr);
if(qr > mid) query(rs, mid + 1, r, ql, qr);
} int main(){
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; ++i)
for(int t = 1; t <= k; ++t)
scanf("%d", &a[i][t]);
build(1, 1, n);
scanf("%d", &q);
while(q--){
int opt, id, l, r;
scanf("%d", &opt);
if(opt == 1){
scanf("%d", &id);
for(int i = 1; i <= k; ++i) scanf("%d", &a[id][i]);
modify(1, 1, n, id);
}
else{
for(int i = 0; i < 35; ++i) ans[i] = -1e9;
scanf("%d%d", &l, &r);
query(1, 1, n, l, r);
int maxx = 0;
for(int s = 0; s < (1 << k); ++s){
maxx = max(maxx, ans[s] + ans[(1 << k) - 1 - s]);
}
printf("%d\n", maxx);
}
}
}

Educational Codeforces Round 56 (Rated for Div. 2) G题(线段树,曼哈顿距离)的更多相关文章

  1. Educational Codeforces Round 81 (Rated for Div. 2)E(线段树)

    预处理把左集划分为大小为1~i-1时,把全部元素都移动到右集的代价,记作sum[i]. 然后枚举终态时左集的大小,更新把元素i 留在/移动到 左集的代价. 树状数组/线段树处理区间修改/区间查询 #d ...

  2. Educational Codeforces Round 73 (Rated for Div. 2)F(线段树,扫描线)

    这道题里线段树用来区间更新(每次给更大的区间加上当前区间的权重),用log的复杂度加快了更新速度,也用了区间查询(查询当前区间向右直至最右中以当前区间端点向右一段区间的和中最大的那一段的和),也用lo ...

  3. Educational Codeforces Round 72 (Rated for Div. 2)E(线段树,思维)

    #define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;#define BUF_SIZE 100000 ...

  4. Educational Codeforces Round 39 (Rated for Div. 2) G

    Educational Codeforces Round 39 (Rated for Div. 2) G 题意: 给一个序列\(a_i(1 <= a_i <= 10^{9}),2 < ...

  5. Multidimensional Queries(二进制枚举+线段树+Educational Codeforces Round 56 (Rated for Div. 2))

    题目链接: https://codeforces.com/contest/1093/problem/G 题目: 题意: 在k维空间中有n个点,每次给你两种操作,一种是将某一个点的坐标改为另一个坐标,一 ...

  6. Educational Codeforces Round 56 (Rated for Div. 2) D. Beautiful Graph 【规律 && DFS】

    传送门:http://codeforces.com/contest/1093/problem/D D. Beautiful Graph time limit per test 2 seconds me ...

  7. Educational Codeforces Round 56 (Rated for Div. 2) ABCD

    题目链接:https://codeforces.com/contest/1093 A. Dice Rolling 题意: 有一个号数为2-7的骰子,现在有一个人他想扔到几就能扔到几,现在问需要扔多少次 ...

  8. Educational Codeforces Round 56 (Rated for Div. 2) D

    给你一个无向图 以及点的个数和边  每个节点只能用1 2 3 三个数字 求相邻 两个节点和为奇数   能否构成以及有多少种构成方法 #include<bits/stdc++.h> usin ...

  9. Educational Codeforces Round 56 (Rated for Div. 2)

    涨rating啦.. 不过话说为什么有这么多数据结构题啊,难道是中国人出的? A - Dice Rolling 傻逼题,可以用一个三加一堆二或者用一堆二,那就直接.. #include<cstd ...

  10. Educational Codeforces Round 56 (Rated for Div. 2) F - Vasya and Array dp好题

    F - Vasya and Array dp[ i ][ j ] 表示用了前 i 个数字并且最后一个数字是 j 的方案数. dp[ i ][ j ] = sumdp [i - 1 ][ j ], 这样 ...

随机推荐

  1. Health Kit基于数据提供专业方案,改善用户睡眠质量

    什么是CBT-I? 中国社科院等机构今年发布的<中国睡眠研究报告2023>内容显示,2022年,受访者的每晚平均睡眠时长为7.40小时,近半数受访者的每晚平均睡眠时长不足8小时(47.55 ...

  2. 抢先体验!超强的 Anchor Positioning 锚点定位

    本文,将向大家介绍 CSS 规范中,最新的 Anchor Positioning,翻译为锚点定位. Anchor Position 的出现,极大的丰富了 CSS 的能力,虽然语法稍显复杂,但是有了它, ...

  3. C#byte数组获取每一位值

    获取byte中每一位的值 byte byData = 0x36; int n0, n1, n2, n3, n4, n5, n6, n7; n0 = (byData & 0x01) == 0x0 ...

  4. Unity UGUI的InputField(输入框)组件的介绍及使用

    UGUI的InputField(输入框)组件的介绍及使用 1. 什么是UGUI的InputField组件? UGUI的InputField组件是Unity中的一个用户界面组件,用于接收用户的输入.它可 ...

  5. JAVA语言基础day01

    笔记: Java开发环境: java编译运行过程: 编译期:.java源文件,经过编译,生成.class字节码文件 运行期:JVM加载.class并运行.class(0和1) 特点:跨平台,一次编译到 ...

  6. elasticsearch wildcard 慢查询原因分析(深入到源码!!!)

    大家好,我是蓝胖子,前段时间线上elasticsearch集群遇到多次wildcard产生的性能问题, elasticsearch wildcard 一直是容易引发elasticsearch 容易宕机 ...

  7. Web攻防--JNDI注入--Log4j漏洞--Fastjson反序列化漏洞

    JNDI注入 什么是JNDI JNDI全称为 Java Naming and Directory Interface(Java命名和目录接口),是一组应用程序接口,为开发人员查找和访问各种资源提供了统 ...

  8. 介绍五个很实用的IDEA使用技巧

    日常开发中,相信广大 Java 开发者都使用过 IntelliJ IDEA 作为开发工具,IntelliJ IDEA 是一款优秀的 Java 集成开发环境,它提供了许多强大的功能和快捷键,可以帮助开发 ...

  9. 【python】python开源代理ip池

    一.前言 随着互联网的不断发展,越来越多的应用需要使用高匿代理IP才能访问目标网站,而代理IP作为一种能够隐藏本机真实IP地址的工具,在网络抓取.搜索引擎排名.广告投放.反爬虫等方面有着广泛的应用场景 ...

  10. Azure Data Factory(九)基础知识回顾

    一,引言 在本文中,我们将继续了解什么是 Azure Data Factory,Azure Data Factory 的工作原理,Azure Data Factory 数据工程中的数据管道,并了解继承 ...