Gym

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

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

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

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

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

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

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

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

无解的情况需要特判一下

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll N=1e5+10,inf=0x3f3f3f3f3f3f3f3fll;
 5 ll n,m,X[N],Y[N],C[N],ka;
 6 struct D {ll mx,smx,mi,smi,umx,umi;} tr[N<<2][2];
 7 D operator+(const D& a,const D& b) {
 8     if(a.mx==~inf)return b;
 9     if(b.mx==~inf)return a;
10     D c;
11     c.mx=max(a.mx,b.mx);
12     c.mi=min(a.mi,b.mi);
13     c.umx=c.mx==a.mx?a.umx:b.umx;
14     c.smx=max(a.smx,b.smx);
15     if(a.umx!=b.umx)c.smx=max(c.smx,min(a.mx,b.mx));
16     c.umi=c.mi==a.mi?a.umi:b.umi;
17     c.smi=min(a.smi,b.smi);
18     if(a.umi!=b.umi)c.smi=min(c.smi,max(a.mi,b.mi));
19     return c;
20 }
21 #define ls (u<<1)
22 #define rs (u<<1|1)
23 #define mid ((l+r)>>1)
24 void pu(ll u) {tr[u][0]=tr[ls][0]+tr[rs][0],tr[u][1]=tr[ls][1]+tr[rs][1];}
25 void build(ll u=1,ll l=1,ll r=n) {
26     if(l==r) {
27         tr[u][0]= {X[l]+Y[l],~inf,X[l]+Y[l],inf,C[l],C[l]};
28         tr[u][1]= {X[l]-Y[l],~inf,X[l]-Y[l],inf,C[l],C[l]};
29         return;
30     }
31     build(ls,l,mid),build(rs,mid+1,r),pu(u);
32 }
33 void upd(ll p,ll x,ll y,ll c,ll u=1,ll l=1,ll r=n) {
34     if(l==r) {
35         tr[u][0]= {x+y,~inf,x+y,inf,c,c};
36         tr[u][1]= {x-y,~inf,x-y,inf,c,c};
37         return;
38     }
39     p<=mid?upd(p,x,y,c,ls,l,mid):upd(p,x,y,c,rs,mid+1,r);
40     pu(u);
41 }
42 D qry(ll L,ll R,ll f,ll u=1,ll l=1,ll r=n) {
43     if(l>=L&&r<=R)return tr[u][f];
44     if(l>R||r<L)return {~inf};
45     return qry(L,R,f,ls,l,mid)+qry(L,R,f,rs,mid+1,r);
46 }
47 int main() {
48     ll T;
49     for(scanf("%lld",&T); T--;) {
50         printf("Case #%lld:
",++ka);
51         scanf("%lld%lld",&n,&m);
52         for(ll i=1; i<=n; ++i)scanf("%lld%lld%lld",&X[i],&Y[i],&C[i]);
53         build();
54         while(m--) {
55             ll f,l,r,k,c,x,y;
56             scanf("%lld",&f);
57             if(f==1)scanf("%lld%lld%lld",&k,&x,&y),upd(k,X[k]+=x,Y[k]+=y,C[k]);
58             else if(f==2)scanf("%lld%lld",&k,&c),upd(k,X[k],Y[k],C[k]=c);
59             else if(f==3) {
60                 scanf("%lld%lld",&l,&r);
61                 D a=qry(l,r,0),b=qry(l,r,1);
62                 ll x=a.umx==a.umi?max(a.mx-a.smi,a.smx-a.mi):a.mx-a.mi;
63                 ll y=b.umx==b.umi?max(b.mx-b.smi,b.smx-b.mi):b.mx-b.mi;
64                 printf("%lld
",a.smx==~inf?0:max(x,y));
65             }
66         }
67     }
68     return 0;
69 }
原文地址:https://www.cnblogs.com/asdfsag/p/11662618.html