• gym/101955/problem/E


    传送门

    思路:  

      这道题要把给定的每个坐标利用切比雪夫坐标表示,这样两个点的距离就是max(dx,dy),而不是一开始的dx + dy,有利于线段树的维护,又由于询问的是区间的最大差值,限制是两个点是属于不同门派的,所以我们可以维护每个区间的最大,次大值,最小次小值。

    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    
    using namespace std;
    #define lson (l , mid , rt << 1)
    #define rson (mid + 1 , r , rt << 1 | 1)
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define pb push_back
    #define pq priority_queue
    
    
    
    typedef long long ll;
    typedef unsigned long long ull;
    //typedef __int128 bll;
    typedef pair<ll ,ll > pll;
    typedef pair<int ,int > pii;
    typedef pair<int,pii> p3;
    typedef pair<ll,int>pli;
    //priority_queue<int> q;//这是一个大根堆q
    //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
    #define fi first
    #define se second
    //#define endl '
    '
    
    #define OKC ios::sync_with_stdio(false);cin.tie(0)
    #define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
    #define REP(i , j , k)  for(int i = j ; i <  k ; ++i)
    #define max3(a,b,c) max(max(a,b), c);
    #define min3(a,b,c) min(min(a,b), c);
    //priority_queue<int ,vector<int>, greater<int> >que;
    
    const ll mos = 0x7FFFFFFF;  //2147483647
    const ll nmos = 0x80000000;  //-2147483648
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f; //18
    const int mod = 9999973;
    const double esp = 1e-8;
    const double PI=acos(-1.0);
    const double PHI=0.61803399;    //黄金分割点
    const double tPHI=0.38196601;
    
    
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
    /*-----------------------showtime----------------------*/
    
                    const int maxn = 5e5+9;
                    int n,m;
                    struct node{
                        ll x,y,c;
                    }a[maxn];
    
                    struct Tree{
                        ///p[0] x轴 1,2 第一第二大,3,4第一第二小
                        ///p[1] y轴
                        pli p[2][5];
                    } t[maxn<<2];
    
    
                    void pushup34(int rt,int id){
                        pli tmp[5];
                        tmp[1] = t[rt<<1].p[id][3];
                        tmp[2] = t[rt<<1].p[id][4];
                        tmp[3] = t[rt<<1|1].p[id][3];
                        tmp[4] = t[rt<<1|1].p[id][4];
    
                        t[rt].p[id][3] = {inff,0};
                        t[rt].p[id][4] = {inff,0};
                        for(int i=1; i<=4; i++){
                            if(t[rt].p[id][3].fi > tmp[i].fi && tmp[i].se){
                                t[rt].p[id][3] = tmp[i];
                            }
                        }
    
                        for(int i=1; i<=4; i++){
                            if(t[rt].p[id][4].fi > tmp[i].fi && tmp[i].se != t[rt].p[id][3].se){
                                t[rt].p[id][4] = tmp[i];
                            }
                        }
    
                    }
                    void pushup12(int rt,int id){
                        pli tmp[5];
                        tmp[1] = t[rt<<1].p[id][1];
                        tmp[2] = t[rt<<1].p[id][2];
                        tmp[3] = t[rt<<1|1].p[id][1];
                        tmp[4] = t[rt<<1|1].p[id][2];
    
                        t[rt].p[id][1] = {-inff,0};
                        t[rt].p[id][2] = {-inff,0};
                        for(int i=1; i<=4; i++){
                            if(t[rt].p[id][1].fi < tmp[i].fi && tmp[i].se){
    
                                t[rt].p[id][1] = tmp[i];
                            }
                        }
    
                        for(int i=1; i<=4; i++){
                            if(t[rt].p[id][2].fi < tmp[i].fi && tmp[i].se != t[rt].p[id][1].se){
                                t[rt].p[id][2] = tmp[i];
                            }
                        }
                    }
                    void build(int l,int r,int rt){
                        if(l == r){
    
                                t[rt].p[0][1].fi = a[l].x; t[rt].p[0][1].se = a[l].c;
                                t[rt].p[0][2] = {-inff,0};
                                t[rt].p[0][3].fi = a[l].x; t[rt].p[0][3].se = a[l].c;
                                t[rt].p[0][4] = {inff,0};
    
                                /*-----------------------*/
                                t[rt].p[1][1].fi = a[l].y; t[rt].p[1][1].se = a[l].c;
                                t[rt].p[1][2] = {-inff,0};
                                t[rt].p[1][3].fi = a[l].y; t[rt].p[1][3].se = a[l].c;
                                t[rt].p[1][4] = {inff,0};
    
                            return;
                        }
                        int mid = (l + r) >> 1;
                        build(l,mid,rt<<1);
                        build(mid+1,r,rt<<1|1);
                        pushup12(rt, 0);  pushup34(rt, 0);
    
                        pushup12(rt, 1);  pushup34(rt, 1);
                    }
    
                    void update(int k,int c,int dx,int dy,int l,int r,int rt){
                        if(l == r){
                            a[l].x += 1ll*dx;
                            a[l].y += 1ll*dy;
                            a[l].c = c;
                                t[rt].p[0][1].fi = a[l].x; t[rt].p[0][1].se = a[l].c;
                                t[rt].p[0][2] = {-inff,0};
                                t[rt].p[0][3].fi = a[l].x; t[rt].p[0][3].se = a[l].c;
                                t[rt].p[0][4] = {inff,0};
    
    
                            //-----------------------------------//
                                t[rt].p[1][1].fi = a[l].y; t[rt].p[1][1].se = a[l].c;
                                t[rt].p[1][2] = {-inff,0};
                                t[rt].p[1][3].fi = a[l].y; t[rt].p[1][3].se = a[l].c;
                                t[rt].p[1][4] = {inff,0};
    
    
    
    
                            return;
                        }
                        int mid = (l + r) >> 1;
                        if(k <= mid) update(k,c,dx,dy,l,mid,rt<<1);
                        else update(k,c,dx,dy,mid+1,r,rt<<1|1);
                        pushup12(rt, 0);  pushup34(rt, 0);
    
                        pushup12(rt, 1);  pushup34(rt, 1);
                    }
    
    
                    void query(int L,int R,int l,int r,int rt,pli &b1,pli &b2,pli &s1, pli &s2,int id){
                            if( L <= l && r <= R){
    
                                for(int i=1; i<=2; i++) {
                                    if(b1.fi < t[rt].p[id][i].fi)
                                        {
                                            if(b1.se != t[rt].p[id][i].se)
                                               b2 = b1;
                                            b1 = t[rt].p[id][i];
                                        }
                                }
                                for(int i=1; i<=2; i++){
                                    if(b2.fi < t[rt].p[id][i].fi && b1.se != t[rt].p[id][i].se){
                                        b2 = t[rt].p[id][i];
                                    }
                                }
    
                                for(int i=3; i<=4; i++) {
                                    if(s1.fi > t[rt].p[id][i].fi){
                                            if(s1.se != t[rt].p[id][i].se)
                                                s2 = s1;
                                            s1 = t[rt].p[id][i];
                                    }
                                }
                                for(int i=3; i<=4; i++){
                                    if(s2.fi > t[rt].p[id][i].fi && s1.se != t[rt].p[id][i].se){
                                        s2 = t[rt].p[id][i];
                                    }
                                }
                                return ;
                            }
    
    
                            int mid = (l + r) >> 1;
                            if(mid >= L)  query(L, R, l, mid, rt<<1, b1,b2,s1,s2,id);
                            if(mid < R)   query(L, R, mid+1, r,rt<<1|1, b1,b2,s1,s2,id);
    
                    }
    int main(){
                int T;  scanf("%d", &T);
                for(int cas=1; cas<=T; cas++){
                    printf("Case #%d:
    ", cas);
                    scanf("%d%d", &n, &m);
                    for(int i=1; i<=n; i++){
                        int x,y,c;
                        scanf("%d%d%d", &x, &y, &c);
                        a[i].x = x + y, a[i].y = x - y;
                        a[i].c = c;
                    }
    
                    build(1,n,1);
    
                    while(m --) {
                            int op;     scanf("%d", &op);
                            if(op == 1){
                                int k,x,y;
                                scanf("%d%d%d", &k, &x, &y);
                                update(k,a[k].c,x+y, x-y,1,n,1);
                            }
                            else if(op == 2){
                                int k,c;
                                scanf("%d%d", &k, &c);
                                update(k,c,0,0,1,n,1);
                            }
                            else {
                                int l,r;
                                scanf("%d%d", &l, &r);
    
    
                                pli q[5];
                                q[1] = q[2] = {-inff, 0};
                                q[3] = q[4] = {inff, 0};
    
    
                                query(l,r,1,n,1,q[1],q[2],q[3],q[4],0);
                                ll res = -inff;
                                for(int i=1; i<=4; i++){
                                    for(int j=1; j<=4; j++){
                                        if(q[i].se != q[j].se && q[i].se && q[j].se){
                                            res = max(res, abs(q[i].fi - q[j].fi));
                                        }
                                    }
                                }
    
    
                                pli e[5];
                                e[1] = e[2] = {-inff, 0};
                                e[3] = e[4] = {inff, 0};
                                query(l,r,1,n,1,e[1],e[2],e[3],e[4],1);
    
                                for(int i=1; i<=4; i++){
                                    for(int j=1; j<=4; j++){
                                        if(e[i].se != e[j].se && e[i].se && e[j].se){
                                            res = max(res, abs(e[i].fi - e[j].fi));
                                        }
                                    }
                                }
    
                                if(res <= -inff) res = 0;
                                printf("%lld
    ", res);
                            }
                    }
                }
    
                return 0;
    }
    View Code
  • 相关阅读:
    给JavaScript新手的24条实用建议
    javascript之HTML(select option)详解
    PHP的正则处理函数总结分析
    多级关联菜单:
    理解json两种结构:数组和对象
    dede标签学习笔记(一)
    Jewel_M PHP定时执行任务的实现
    网站刷新器
    PHP_SELF、 SCRIPT_NAME、 REQUEST_URI区别
    RemoveXSS()
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/10318683.html
Copyright © 2020-2023  润新知