zoukankan      html  css  js  c++  java
  • CodeForces

    题意:给定N个K维的点,Q次操作,或者修改点的坐标;或者问[L,R]这些点中最远的点。

    思路:因为最后一定可以表示维+/-(x1-x2)+/-(y1-y2)+/-(z1-z2).....

    所以我们可以保存到线段树里,每次求区间最大值和最小值即可。

    注意到我们可以先确定一个点的正负号,所以时间和空间节省了一半。

    #include<bits/stdc++.h>
    #define mp make_pair
    #define pii pair<int,int>
    #define F first
    #define S second
    #define lson Now<<1
    #define rson Now<<1|1
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=800000;
    const int inf=1000000000;
    struct T
    {
        int Mx[maxn],Mn[maxn];
        void update(int Now,int L,int R,int pos,int val)
        {
            if(L==R){ Mn[Now]=Mx[Now]=val; return ;}
            int Mid=(L+R)>>1;
            if(pos<=Mid) update(lson,L,Mid,pos,val);
            else update(rson,Mid+1,R,pos,val);
            Mx[Now]=max(Mx[lson],Mx[rson]); Mn[Now]=min(Mn[lson],Mn[rson]);
        }
        pii query(int Now,int L,int R,int l,int r)
        {
            if(l<=L&&r>=R) return mp(Mx[Now],Mn[Now]);
            int Mid=(L+R)>>1; int mx=-inf,mn=inf; pii tmp;
            if(l<=Mid){
                tmp=query(lson,L,Mid,l,r);
                mx=max(mx,tmp.F); mn=min(mn,tmp.S);
            }
            if(r>Mid){
                tmp=query(rson,Mid+1,R,l,r);
                mx=max(mx,tmp.F); mn=min(mn,tmp.S);
            }
            return mp(mx,mn);
        }
    }t[16];
    int main()
    {
        int N,K,M,opt,L,R,p,x[6],KK;
        scanf("%d%d",&N,&K); KK=(1<<(K-1))-1;
        rep(i,0,KK){
            rep(j,0,N*4) t[i].Mn[j]=inf,t[i].Mx[j]=-inf;
        }
        rep(i,1,N){
            rep(j,0,K-1) scanf("%d",&x[j]);
            rep(j,0,KK) {
                int tmp=0;
                rep(k,0,K-1) if(j&(1<<k)) tmp+=x[k];else tmp-=x[k];
                t[j].update(1,1,N,i,tmp);
            }
        }
        scanf("%d",&M);
        rep(i,1,M){
            scanf("%d",&opt);
            if(opt==2){
                scanf("%d%d",&L,&R);
                int ans=-inf; pii tmp;
                rep(j,0,KK){
                   pii tmp=t[j].query(1,1,N,L,R);
                   ans=max(ans,tmp.F-tmp.S);
                   ans=max(ans,tmp.S-tmp.F);
                }
                printf("%d
    ",ans);
            }
            else {
                scanf("%d",&p); rep(j,0,K-1) scanf("%d",&x[j]);
                rep(j,0,KK) {
                    int tmp=0;
                    rep(k,0,K-1) if(j&(1<<k)) tmp+=x[k];else tmp-=x[k];
                    t[j].update(1,1,N,p,tmp);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    HDU 2853 (KM最大匹配)
    HDU 2852 (树状数组+无序第K小)
    HDU 2851 (最短路)
    HDU 2846 (AC自动机+多文本匹配)
    MyBatis使用示例
    Hessian示例:Java和C#通信
    SQL Server2005配置同步复制
    【问】如何应对关系型数据库中列的不断增加
    Prolog学习:数独和八皇后问题
    Prolog学习:基本概念
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10126497.html
Copyright © 2011-2022 走看看