题意:有n个忍者(编号为1-n),每个忍者有三个属性:横坐标x,纵坐标y,所属门派c,要求支持三种操作:

1.改变第k个忍者的位置

2.改变第k个忍者的门派

3.查询编号为[l,r]之间的忍者中,所属门派不同的两个忍者的最大曼哈顿距离

通过曼哈顿距离变换,将每个忍者的横坐标和纵坐标拆成x+y和x-y,两种情况分别用线段树维护区间最大值,最小值,最大值和最小值所属门派,以及门派不同的次大值及次小值(非严格),查询时分两种情况:

1.最大值和最小值门派不同:答案为最大值-最小值

2.最大值和最小值门派相同:答案为max(最大值-次小值,次大值-最小值)

两种情况分别讨论一下,然后取个最大值即可。

无解的情况需要特判一下

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+,inf=0x3f3f3f3f3f3f3f3fll;
ll n,m,X[N],Y[N],C[N],ka;
struct D {ll mx,smx,mi,smi,umx,umi;} tr[N<<][];
D operator+(const D& a,const D& b) {
if(a.mx==~inf)return b;
if(b.mx==~inf)return a;
D c;
c.mx=max(a.mx,b.mx);
c.mi=min(a.mi,b.mi);
c.umx=c.mx==a.mx?a.umx:b.umx;
c.smx=max(a.smx,b.smx);
if(a.umx!=b.umx)c.smx=max(c.smx,min(a.mx,b.mx));
c.umi=c.mi==a.mi?a.umi:b.umi;
c.smi=min(a.smi,b.smi);
if(a.umi!=b.umi)c.smi=min(c.smi,max(a.mi,b.mi));
return c;
}
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
void pu(ll u) {tr[u][]=tr[ls][]+tr[rs][],tr[u][]=tr[ls][]+tr[rs][];}
void build(ll u=,ll l=,ll r=n) {
if(l==r) {
tr[u][]= {X[l]+Y[l],~inf,X[l]+Y[l],inf,C[l],C[l]};
tr[u][]= {X[l]-Y[l],~inf,X[l]-Y[l],inf,C[l],C[l]};
return;
}
build(ls,l,mid),build(rs,mid+,r),pu(u);
}
void upd(ll p,ll x,ll y,ll c,ll u=,ll l=,ll r=n) {
if(l==r) {
tr[u][]= {x+y,~inf,x+y,inf,c,c};
tr[u][]= {x-y,~inf,x-y,inf,c,c};
return;
}
p<=mid?upd(p,x,y,c,ls,l,mid):upd(p,x,y,c,rs,mid+,r);
pu(u);
}
D qry(ll L,ll R,ll f,ll u=,ll l=,ll r=n) {
if(l>=L&&r<=R)return tr[u][f];
if(l>R||r<L)return {~inf};
return qry(L,R,f,ls,l,mid)+qry(L,R,f,rs,mid+,r);
}
int main() {
ll T;
for(scanf("%lld",&T); T--;) {
printf("Case #%lld:\n",++ka);
scanf("%lld%lld",&n,&m);
for(ll i=; i<=n; ++i)scanf("%lld%lld%lld",&X[i],&Y[i],&C[i]);
build();
while(m--) {
ll f,l,r,k,c,x,y;
scanf("%lld",&f);
if(f==)scanf("%lld%lld%lld",&k,&x,&y),upd(k,X[k]+=x,Y[k]+=y,C[k]);
else if(f==)scanf("%lld%lld",&k,&c),upd(k,X[k],Y[k],C[k]=c);
else if(f==) {
scanf("%lld%lld",&l,&r);
D a=qry(l,r,),b=qry(l,r,);
ll x=a.umx==a.umi?max(a.mx-a.smi,a.smx-a.mi):a.mx-a.mi;
ll y=b.umx==b.umi?max(b.mx-b.smi,b.smx-b.mi):b.mx-b.mi;
printf("%lld\n",a.smx==~inf?:max(x,y));
}
}
}
return ;
}

最新文章

  1. MiniProfiler(MiniProfiler.EF6监控调试MVC5和EF6的性能)
  2. Rotate Image
  3. ABBYY FineReader 12对系统有哪些要求
  4. SAP第一轮面试总结
  5. 数据结构-链表实现删除全部特定元素x
  6. AspNetPager常用属性及一些样式(本文摘自网络,作者:x123jing)
  7. 收藏的博客--Ogre
  8. dd大牛的《背包九讲》
  9. oracle 存储过程和函数例子 --2
  10. matlab中的三维坐标系与旋转
  11. Es kibana
  12. WebDriver获取table的内容(通过动态获取Table单元格的TagName对其innerHTML值进行获取)
  13. macaca测试web小例子
  14. gradle发布jar包
  15. 使用vue全家桶制作博客网站
  16. LeetCode算法题-Assign Cookies(Java实现)
  17. [转载]vb 时间戳与时间互转
  18. Unix awk的流程控制BEGIN和END的讲解
  19. 李宏毅机器学习笔记5:CNN卷积神经网络
  20. Command Analyze failed with a nonzero exit code

热门文章

  1. Go语言入门篇-JSON&amp;http调用
  2. Golang语言细节小结
  3. JS触发事件集锦
  4. 关于js中this指向的问题
  5. Python全栈开发之6、面向对象
  6. 2019牛客暑期多校训练营(第七场)-H Pair(数位dp)
  7. Infix to Prefix conversion using two stacks
  8. redis db0-15 的概念
  9. LC 752 Open the Lock
  10. linux下安装anconda3