神秘题目4
题目描述
给定二维平面内不同颜色的 \(n\) 个点,你需要写一个程序完成一下2种操作。
- 将第 \(k\) 个点的坐标改成 \((x,y)\),颜色改成 \(c\) 。
- 求第 \(L\) 到 \(R\) 个点中,两两不同颜色的点的曼哈顿距离最大值(若不存在输出0)。
输入格式
第一行 2 个整数 \(n\),\(m\) 。
接下来 \(n\) 行,每行 3 个整数 \(x,y,c\) 描述第 \(i\) 个点的坐标和颜色。
接下来 \(m\) 行,每行第一个整数 \(opt\)
- 若 \(opt=1\) ,接下来 3 个整数 \(x,y,c\) 表示一次修改操作
- 若 \(opt=2\),接下来 2 个整数 \(L,R\) 表示一次查询操作
输出格式
若干行每行一个整数,对应一次查询操作的答案。
样例输入
5 5
-5 1 6
2 1 3
-5 7 3
-5 1 7
9 -9 9
1 1 -1 7 3
2 1 2
2 1 4
1 4 1 -9 5
2 2 5
样例输出
0
10
30
数据范围与约定
对于 \(10\%\) 的数据 \(n,m,|x|,|y|,c<=10\)
对于 \(30\%\) 的数据 \(n,m<=1000\)
另有 \(10\%\) 的数据 \(0<=x,y<=5\) 任何时刻点的颜色各不相同,无修改
另有 \(10\%\) 的数据 \(x=y\)
另有 \(10\%\) 的数据 \(|x|=|y|\)
对于 \(100\%\) 的数据 \(n,m<=1e5,|x|,|y|,c<=1e9\)
时间限制:\(1s\)
空间限制:\(256MB\)
题解
10分做法
有脚就行
30分做法
有手就行
另外10分
注意到坐标值域非常小而且没修改颜色还都不一样,那这就很好办了。直接差分求 \((x+y),(x-y)\) 的值有多少个,而不是求\((x,y)\)有多少个,最后扫描一下就行了。复杂度 \(O(n+q)\) 。
另外10分
线段树维护 \(max(x)-min(x)\),注意要留一个次大值和次小值(其颜色若和最大最小值同色,顺延到次次大值,次次小值)处理 \(max(x)\) 和 \(min(x)\) 这两个点颜色相同这种情况。
另外10分
还真不会针对这一档的做法
满分做法
线段树维护 \(max(max(x+y)-min(x+y),max(x-y)-min(x-y))\) ,注意要留一个次大值和次小值(其颜色若和最大最小值同色,顺延到次次大值,次次小值)处理 \(max(x\pm y)\) 和 \(min(x \pm y)\) 这两个点颜色相同这种情况,代码非常简单。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int inf=1<<30;
int n,m,C[100010];
LL X[100010],Y[100010];
int addcMAX,addcMax,addcMIN,addcMin;
LL addMAX,addMax,addMIN,addMin;
int subcMAX,subcMax,subcMIN,subcMin;
LL subMAX,subMax,subMIN,subMin;
struct SegmentTree
{int l,r,addcMAX,addcMax,addcMIN,addcMin,subcMAX,subcMax,subcMIN,subcMin;LL addMAX,addMax,addMIN,addMin,subMAX,subMax,subMIN,subMin,x,y;}st[400010];
inline int read()
{
int x=0;bool w=0;char ch=0;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return w?-x:x;
}
void upd(int p)
{
st[p].addMAX=st[p].addMax=-inf;
st[p].addMIN=st[p].addMin=inf;
st[p].addcMAX=st[p].addcMax=st[p].addcMIN=st[p].addcMin=-10086;
if(st[p<<1].addMAX>st[p].addMAX){
if(st[p<<1].addcMAX!=st[p].addcMAX)
st[p].addMax=st[p].addMAX,st[p].addcMax=st[p].addcMAX;
st[p].addMAX=st[p<<1].addMAX;
st[p].addcMAX=st[p<<1].addcMAX;
}
if(st[p<<1].addMAX>st[p].addMax&&st[p<<1].addMAX<=st[p].addMAX&&st[p<<1].addcMAX!=st[p].addcMAX){
st[p].addMax=st[p<<1].addMAX;
st[p].addcMax=st[p<<1].addcMAX;
}
if(st[p<<1].addMax>st[p].addMax&&st[p<<1].addcMax!=st[p].addcMAX){
st[p].addMax=st[p<<1].addMax;
st[p].addcMax=st[p<<1].addcMax;
}
if(st[p<<1].addMIN<st[p].addMIN){
if(st[p<<1].addcMIN!=st[p].addcMIN)
st[p].addMin=st[p].addMIN,st[p].addcMin=st[p].addcMIN;
st[p].addMIN=st[p<<1].addMIN;
st[p].addcMIN=st[p<<1].addcMIN;
}
if(st[p<<1].addMIN<st[p].addMin&&st[p<<1].addMIN>=st[p].addMIN&&st[p<<1].addcMIN!=st[p].addcMIN){
st[p].addMin=st[p<<1].addMIN;
st[p].addcMin=st[p<<1].addcMIN;
}
if(st[p<<1].addMin<st[p].addMin&&st[p<<1].addcMin!=st[p].addcMIN){
st[p].addMin=st[p<<1].addMin;
st[p].addcMin=st[p<<1].addcMin;
}
if(st[p<<1|1].addMAX>st[p].addMAX){
if(st[p<<1|1].addcMAX!=st[p].addcMAX)
st[p].addMax=st[p].addMAX,st[p].addcMax=st[p].addcMAX;
st[p].addMAX=st[p<<1|1].addMAX;
st[p].addcMAX=st[p<<1|1].addcMAX;
}
if(st[p<<1|1].addMAX>st[p].addMax&&st[p<<1|1].addMAX<=st[p].addMAX&&st[p<<1|1].addcMAX!=st[p].addcMAX){
st[p].addMax=st[p<<1|1].addMAX;
st[p].addcMax=st[p<<1|1].addcMAX;
}
if(st[p<<1|1].addMax>st[p].addMax&&st[p<<1|1].addcMax!=st[p].addcMAX){
st[p].addMax=st[p<<1|1].addMax;
st[p].addcMax=st[p<<1|1].addcMax;
}
if(st[p<<1|1].addMIN<st[p].addMIN){
if(st[p<<1|1].addcMIN!=st[p].addcMIN)
st[p].addMin=st[p].addMIN,st[p].addcMin=st[p].addcMIN;
st[p].addMIN=st[p<<1|1].addMIN;
st[p].addcMIN=st[p<<1|1].addcMIN;
}
if(st[p<<1|1].addMIN<st[p].addMin&&st[p<<1|1].addMIN>=st[p].addMIN&&st[p<<1|1].addcMIN!=st[p].addcMIN){
st[p].addMin=st[p<<1|1].addMIN;
st[p].addcMin=st[p<<1|1].addcMIN;
}
if(st[p<<1|1].addMin<st[p].addMin&&st[p<<1|1].addcMin!=st[p].addcMIN){
st[p].addMin=st[p<<1|1].addMin;
st[p].addcMin=st[p<<1|1].addcMin;
}
st[p].subMAX=st[p].subMax=-inf;
st[p].subMIN=st[p].subMin=inf;
st[p].subcMAX=st[p].subcMax=st[p].subcMIN=st[p].subcMin=-10086;
if(st[p<<1].subMAX>st[p].subMAX){
if(st[p<<1].subcMAX!=st[p].subcMAX)
st[p].subMax=st[p].subMAX,st[p].subcMax=st[p].subcMAX;
st[p].subMAX=st[p<<1].subMAX;
st[p].subcMAX=st[p<<1].subcMAX;
}
if(st[p<<1].subMAX>st[p].subMax&&st[p<<1].subMAX<=st[p].subMAX&&st[p<<1].subcMAX!=st[p].subcMAX){
st[p].subMax=st[p<<1].subMAX;
st[p].subcMax=st[p<<1].subcMAX;
}
if(st[p<<1].subMax>st[p].subMax&&st[p<<1].subcMax!=st[p].subcMAX){
st[p].subMax=st[p<<1].subMax;
st[p].subcMax=st[p<<1].subcMax;
}
if(st[p<<1].subMIN<st[p].subMIN){
if(st[p<<1].subcMIN!=st[p].subcMIN)
st[p].subMin=st[p].subMIN,st[p].subcMin=st[p].subcMIN;
st[p].subMIN=st[p<<1].subMIN;
st[p].subcMIN=st[p<<1].subcMIN;
}
if(st[p<<1].subMIN<st[p].subMin&&st[p<<1].subMIN>=st[p].subMIN&&st[p<<1].subcMIN!=st[p].subcMIN){
st[p].subMin=st[p<<1].subMIN;
st[p].subcMin=st[p<<1].subcMIN;
}
if(st[p<<1].subMin<st[p].subMin&&st[p<<1].subcMin!=st[p].subcMIN){
st[p].subMin=st[p<<1].subMin;
st[p].subcMin=st[p<<1].subcMin;
}
if(st[p<<1|1].subMAX>st[p].subMAX){
if(st[p<<1|1].subcMAX!=st[p].subcMAX)
st[p].subMax=st[p].subMAX,st[p].subcMax=st[p].subcMAX;
st[p].subMAX=st[p<<1|1].subMAX;
st[p].subcMAX=st[p<<1|1].subcMAX;
}
if(st[p<<1|1].subMAX>st[p].subMax&&st[p<<1|1].subMAX<=st[p].subMAX&&st[p<<1|1].subcMAX!=st[p].subcMAX){
st[p].subMax=st[p<<1|1].subMAX;
st[p].subcMax=st[p<<1|1].subcMAX;
}
if(st[p<<1|1].subMax>st[p].subMax&&st[p<<1|1].subcMax!=st[p].subcMAX){
st[p].subMax=st[p<<1|1].subMax;
st[p].subcMax=st[p<<1|1].subcMax;
}
if(st[p<<1|1].subMIN<st[p].subMIN){
if(st[p<<1|1].subcMIN!=st[p].subcMIN)
st[p].subMin=st[p].subMIN,st[p].subcMin=st[p].subcMIN;
st[p].subMIN=st[p<<1|1].subMIN;
st[p].subcMIN=st[p<<1|1].subcMIN;
}
if(st[p<<1|1].subMIN<st[p].subMin&&st[p<<1|1].subMIN>=st[p].subMIN&&st[p<<1|1].subcMIN!=st[p].subcMIN){
st[p].subMin=st[p<<1|1].subMIN;
st[p].subcMin=st[p<<1|1].subcMIN;
}
if(st[p<<1|1].subMin<st[p].subMin&&st[p<<1|1].subcMin!=st[p].subcMIN){
st[p].subMin=st[p<<1|1].subMin;
st[p].subcMin=st[p<<1|1].subcMin;
}
}
void build(int p,int l,int r)
{
st[p].l=l;st[p].r=r;
st[p].addMAX=st[p].addMax=-inf;
st[p].addMIN=st[p].addMin=inf;
st[p].addcMAX=st[p].addcMax=st[p].addcMIN=st[p].addcMin=-10086;
st[p].subMAX=st[p].subMax=-inf;
st[p].subMIN=st[p].subMin=inf;
st[p].subcMAX=st[p].subcMax=st[p].subcMIN=st[p].subcMin=-10086;
if(l==r){
st[p].addcMAX=st[p].addcMIN=C[l];
st[p].addMAX=X[l]+Y[l];
st[p].addMIN=X[l]+Y[l];
//st[p<<1].addMAX=st[p<<1].addMax=st[p<<1|1].addMAX=st[p<<1|1].addMax=-inf;
//st[p<<1].addMIN=st[p<<1].addMin=st[p<<1|1].addMIN=st[p<<1|1].addMin=inf;
st[p].subcMAX=st[p].subcMIN=C[l];
st[p].subMAX=X[l]-Y[l];
st[p].subMIN=X[l]-Y[l];
//st[p<<1].subMAX=st[p<<1].subMax=st[p<<1|1].subMAX=st[p<<1|1].subMax=-inf;
//st[p<<1].subMIN=st[p<<1].subMin=st[p<<1|1].subMIN=st[p<<1|1].subMin=inf;
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
upd(p);
}
void change(int p,int pos)
{
if(st[p].l==st[p].r){
st[p].addcMAX=st[p].addcMIN=C[pos];
st[p].addMAX=X[pos]+Y[pos];
st[p].addMIN=X[pos]+Y[pos];
st[p].subcMAX=st[p].subcMIN=C[pos];
st[p].subMAX=X[pos]-Y[pos];
st[p].subMIN=X[pos]-Y[pos];
return;
}
int mid=(st[p].l+st[p].r)>>1;
if(pos<=mid)change(p<<1,pos);
else change(p<<1|1,pos);
upd(p);
}
void ask(int p,int l,int r)
{
if(l<=st[p].l&&st[p].r<=r){
if(st[p].addMAX>addMAX){
if(st[p].addcMAX!=addcMAX)addMax=addMAX,addcMax=addcMAX;
addMAX=st[p].addMAX;addcMAX=st[p].addcMAX;
}
if(st[p].addMAX>addMax&&st[p].addMAX<=addMAX&&st[p].addcMAX!=addcMAX)
addMax=st[p].addMAX,addcMax=st[p].addcMAX;
if(st[p].addMax>addMax&&st[p].addcMax!=addcMAX)
addMax=st[p].addMax,addcMax=st[p].addcMax;
if(st[p].addMIN<addMIN){
if(st[p].addcMIN!=addcMIN)addMin=addMIN,addcMin=addcMIN;
addMIN=st[p].addMIN;addcMIN=st[p].addcMIN;
}
if(st[p].addMIN<addMin&&st[p].addMIN>=addMIN&&st[p].addcMIN!=addcMIN)
addMin=st[p].addMIN,addcMin=st[p].addcMIN;
if(st[p].addMin<addMin&&st[p].addcMin!=addcMIN)
addMin=st[p].addMin,addcMin=st[p].addcMin;
if(st[p].subMAX>subMAX){
if(st[p].subcMAX!=subcMAX)subMax=subMAX,subcMax=subcMAX;
subMAX=st[p].subMAX;subcMAX=st[p].subcMAX;
}
if(st[p].subMAX>subMax&&st[p].subMAX<=subMAX&&st[p].subcMAX!=subcMAX)
subMax=st[p].subMAX,subcMax=st[p].subcMAX;
if(st[p].subMax>subMax&&st[p].subcMax!=subcMAX)
subMax=st[p].subMax,subcMax=st[p].subcMax;
if(st[p].subMIN<subMIN){
if(st[p].subcMIN!=subcMIN)subMin=subMIN,subcMin=subcMIN;
subMIN=st[p].subMIN;subcMIN=st[p].subcMIN;
}
if(st[p].subMIN<subMin&&st[p].subMIN>=subMIN&&st[p].subcMIN!=subcMIN)
subMin=st[p].subMIN,subcMin=st[p].subcMIN;
if(st[p].subMin<subMin&&st[p].subcMin!=subcMIN)
subMin=st[p].subMin,subcMin=st[p].subcMin;
return;
}
int mid=(st[p].l+st[p].r)>>1;
if(l<=mid)ask(p<<1,l,r);
if(r>mid)ask(p<<1|1,l,r);
}
LL calc()
{
LL temp=0;
if(addcMAX!=addcMIN)temp=max(temp,addMAX-addMIN);
if(addcMAX!=addcMin)temp=max(temp,addMAX-addMin);
if(addcMax!=addcMIN)temp=max(temp,addMax-addMIN);
if(subcMAX!=subcMIN)temp=max(temp,subMAX-subMIN);
if(subcMAX!=subcMin)temp=max(temp,subMAX-subMin);
if(subcMax!=subcMIN)temp=max(temp,subMax-subMIN);
return temp;
}
int main()
{
freopen("dis.in","r",stdin);
freopen("dis.out","w",stdout);
n=read();m=read();
for(int i=1;i<=n;i++)
X[i]=read(),Y[i]=read(),C[i]=read();
build(1,1,n);
while(m--){
int opt=read(),l=read(),r=read();
if(opt&1){
X[l]=r;Y[l]=read();C[l]=read();
change(1,l);
}else{
addMAX=addMax=-inf;addMIN=addMin=inf;
addcMAX=addcMax=addcMIN=addcMin=-10086;
subMAX=subMax=-inf;subMIN=subMin=inf;
subcMAX=subcMax=subcMIN=subcMin=-10086;
ask(1,l,r);
printf("%lld\n",calc());
}
}
}