Codeforces 1093G题解(线段树维护k维空间最大曼哈顿距离)
题意是,给出n个k维空间下的点,然后q次操作,每次操作要么修改其中一个点的坐标,要么查询下标为[l,r]区间中所有点中两点的最大曼哈顿距离。
思路:参考blog:https://blog.csdn.net/Anxdada/article/details/81980574,里面讲了k维空间中的最大曼哈顿距离求法,然后利用这个方案改一改,用线段树来维护这些值就好了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(x) memset(x,0,sizeof x)
#define lson o*2
#define rson o*2+1
#define m (l+r)/2
const int maxn=;
struct node
{
int mi,mx;
}tr[*maxn][];
void pushup(int o,int idx)
{
tr[o][idx].mi=min(tr[lson][idx].mi,tr[rson][idx].mi);
tr[o][idx].mx=max(tr[lson][idx].mx,tr[rson][idx].mx);
}
int tmp[maxn][];
int a[maxn][];
void build(int o,int l,int r,int idx);
void update(int o,int l,int r,int x,int idx);
int cal(int n,int k)
{
int ans = , mi, mx, t;
for (int s = ; s < (<<k) ; s ++)
{
mi = 1e9, mx = -1e9;
for (int i = ; i <= n ; i++)
{
t = a[i][];
for (int j = ; j < k ; j++)
{
if ((<<j) & s) t += a[i][j];
else t -= a[i][j];
}
mi = min(mi, t);
mx = max(mx, t);
tmp[i][s]=t;
}
build(,,n,s);
ans = max(ans, mx-mi);
}
return ans;
}
int cal2(int x,int n,int k)
{
int t;
for (int s = ; s < (<<k) ; s ++)
{
int i=x;
t = a[i][];
for (int j = ; j < k ; j++)
{
if ((<<j) & s) t += a[i][j];
else t -= a[i][j];
}
tmp[i][s]=t;
update(,,n,i,s);
}
}
void build(int o,int l,int r,int idx)
{
if(l==r)
{
tr[o][idx].mi=tr[o][idx].mx=tmp[l][idx];
return;
}
build(lson,l,m,idx);
build(rson,m+,r,idx);
pushup(o,idx);
}
void update(int o,int l,int r,int x,int idx)
{
if(l==r)
{
tr[o][idx].mi=tr[o][idx].mx=tmp[l][idx];
return;
}
if(x<=m) update(lson,l,m,x,idx);
else update(rson,m+,r,x,idx);
pushup(o,idx);
}
int query(int o,int l,int r,int ql,int qr,int mark,int idx)
{
if(ql<=l&&qr>=r)
{
if(mark==)
return tr[o][idx].mi;
else
return tr[o][idx].mx;
}
if(qr<=m)
return query(lson,l,m,ql,qr,mark,idx);
if(ql>m)
return query(rson,m+,r,ql,qr,mark,idx);
if(mark==)
return min(query(lson,l,m,ql,qr,mark,idx),query(rson,m+,r,ql,qr,mark,idx));
else
return max(query(lson,l,m,ql,qr,mark,idx),query(rson,m+,r,ql,qr,mark,idx));
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)
for(int j=;j<k;j++)
scanf("%d",&a[i][j]);
cal(n,k);
int q;
scanf("%d",&q);
while(q--)
{
int op;
scanf("%d",&op);
if(op==)
{
int x;
scanf("%d",&x);
for(int i=;i<k;i++)
scanf("%d",&a[x][i]);
cal2(x,n,k);
}
else
{
int l,r;
scanf("%d%d",&l,&r);
int ans=;
for (int s = ; s < (<<k) ; s ++)
{
int mi=1e9;
int mx=-1e9;
mi=min(mi,query(,,n,l,r,,s));
mx=max(mx,query(,,n,l,r,,s));
ans=max(ans,mx-mi);
}
printf("%d\n",ans);
}
}
}
Codeforces 1093G题解(线段树维护k维空间最大曼哈顿距离)的更多相关文章
- 线段树区间合并+k维空间的曼哈顿距离——cf1093G好题
和去年多校的CSGO一样,用状态压缩来求Manhattan距离的最大值 然后要用线段树维护一下区间最大值 /* k维空间给定n个点,两个操作 1 i b1 b2 .. bk : 修改第i个点的坐标 2 ...
- CodeForces - 1093G:Multidimensional Queries (线段树求K维最远点距离)
题意:给定N个K维的点,Q次操作,或者修改点的坐标:或者问[L,R]这些点中最远的点. 思路:因为最后一定可以表示维+/-(x1-x2)+/-(y1-y2)+/-(z1-z2)..... 所以我们可以 ...
- CodeForces - 1263E(线段树维护前缀和最值)
题意 https://vjudge.net/problem/CodeForces-1263E 您要设计一个只有一行的打字机,这一行的长度是无限大,一开始可以认为每个字符都是空.您的打字机有一个光标只指 ...
- 洛谷 P4198 楼房重建 线段树维护单调栈
P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...
- 【uoj#164】[清华集训2015]V 线段树维护历史最值
题目描述 给你一个长度为 $n$ 的序列,支持五种操作: $1\ l\ r\ x$ :将 $[l,r]$ 内的数加上 $x$ :$2\ l\ r\ x$ :将 $[l,r]$ 内的数减去 $x$ ,并 ...
- 【bzoj3064】Tyvj 1518 CPU监控 线段树维护历史最值
题目描述 给你一个序列,支持4种操作:1.查询区间最大值:2.查询区间历史最大值:3.区间加:4.区间赋值. 输入 第一行一个正整数T,表示Bob需要监视CPU的总时间. 然后第二行给出T个数表示在你 ...
- CF877E Danil and a Part-time Job 线段树维护dfs序
\(\color{#0066ff}{题目描述}\) 有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0 共有 m 次操作,操作分为两种 get 询问一个点 x 的子树里有多少个 1 ...
- Codeforces 834D The Bakery【dp+线段树维护+lazy】
D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...
- Codeforces 1368H - Breadboard Capacity(最小割+线段树维护矩阵乘法)
Easy version:Codeforces 题面传送门 & 洛谷题面传送门 Hard version:Codeforces 题面传送门 & 洛谷题面传送门 首先看到这种从某一种颜色 ...
随机推荐
- 【转】Activity生命周期详解
三个循环 提供两个关于Activity的生命周期模型图示帮助理解: 图1 图2 从图2所示的Activity生命周期 ...
- Yarn下Map数控制
public List<InputSplit> getSplits(JobContext job) throws IOException { long minSize = Math.max ...
- SpringBoot非官方教程 | 第二十五篇:2小时学会springboot
转载请标明出处: http://blog.csdn.net/forezp/article/details/61472783 本文出自方志朋的博客 一.什么是spring boot Takes an o ...
- Shell 入门笔记(一)
Shell简介 在开发过程中Linux系统经常接触和使用的,Shell 是我们用户使用 Linux 的桥梁,是C 语言编写的程序.Shell 是一种命令语言,同时一种程序设计语言.对大多数开发人员来说 ...
- Python面向对象--高级(一)
## 属性的类型 - 属性可分为类属性和实例属性 - 实例属性可以通过在类中使用self定义,或者直接在类外部使用实例变量定义 class Person(object): def __init__(s ...
- python__系统 : socket_TCP补充,协程
TCP 三次握手: SYN --> SYN+ACK --> ACK 四次挥手: FIN --> ACK (FIN) --> ACK TCP十种状态: LISTEN ...
- ajax 传递文件成功时 jQuery提示parsererror错误
后台返回值类型 改为:PrintWriter out = response.getWriter();String jsonStr = "{\"success\":\&qu ...
- mysql 安装常用命令,卸载不干净等
安装mysql apt-get install mysql-server apt-get install mysql-client sudo apt-get install libmysqlclien ...
- Redis和Mecahe的简介
Memcache介绍 概念:Memcache是一个高性能,分布式内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果等. ...
- SpringMVC---简单登录例子
所需jar包aopalliance-1.0.jar.commons-logging-1.2.jar.spring-aop-5.0.0.RELEASE.jar.spring-beans-5.0.0.RE ...