• UVALive


    题意:给你一个矩阵,q次操作,每次查询长宽l的矩阵最大值a和最小值b,然后把中间点换成floor((a+b)/2),

    解法:暴力可过,建n颗线段树暴力更新,但是正解应该是树套树,树套树需要注意的是当建树或修改时pushup操作不能直接搞,要先判断是不是外面层的叶子节点,如果是直接修改,如果不是,应该是从外面层的对应子节点更新过来,因为此时的外层树维护的是x轴区间最大和区间最小,需要从x轴两个更小的区间树合并起来更新

    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-8;
    const int N=800+10,maxn=5000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
    
    int c[N][N],n;
    struct segtreeinsegtree{
        int ma[N<<2][N<<2],mi[N<<2][N<<2];
        bool leaf;
        void pushupx(int id,int rt)
        {
            ma[id][rt]=max(ma[id<<1][rt],ma[id<<1|1][rt]);
            mi[id][rt]=min(mi[id<<1][rt],mi[id<<1|1][rt]);
        }
        void pushupy(int id,int rt)
        {
            ma[id][rt]=max(ma[id][rt<<1],ma[id][rt<<1|1]);
            mi[id][rt]=min(mi[id][rt<<1],mi[id][rt<<1|1]);
        }
        void buildy(int id,int x,int l,int r,int rt)
        {
            if(l==r)
            {
                if(leaf)ma[id][rt]=mi[id][rt]=c[x][l];
                else pushupx(id,rt);//,printf("%d %d %d %d
    ",id,x,ma[id][rt]);
                return ;
            }
            int m=(l+r)>>1;
            buildy(id,x,ls);buildy(id,x,rs);
            pushupy(id,rt);
        }
        void buildx(int xl,int xr,int rt,int yl,int yr)
        {
            if(xl==xr){leaf=1;buildy(rt,xl,yl,yr,1);return ;}
            int m=(xl+xr)>>1;
            buildx(xl,m,rt<<1,yl,yr);
            buildx(m+1,xr,rt<<1|1,yl,yr);
            leaf=0,buildy(rt,xl,yl,yr,1);
        }
        void updatey(int id,int posx,int posy,int c,int l,int r,int rt)
        {
            if(l==r)
            {
                if(leaf)ma[id][rt]=mi[id][rt]=c;
                else pushupx(id,rt);
                return ;
            }
            int m=(l+r)>>1;
            if(posy<=m)updatey(id,posx,posy,c,ls);
            else updatey(id,posx,posy,c,rs);
            pushupy(id,rt);
        }
        void updatex(int posx,int posy,int c,int l,int r,int rt)
        {
            if(l==r){leaf=1;updatey(rt,posx,posy,c,1,n,1);return ;}
            int m=(l+r)>>1;
            if(posx<=m)updatex(posx,posy,c,ls);
            else updatex(posx,posy,c,rs);
            leaf=0,updatey(rt,posx,posy,c,1,n,1);
        }
        int querymay(int id,int L,int R,int l,int r,int rt)
        {
            if(L<=l&&r<=R)return ma[id][rt];
            int m=(l+r)>>1,ans=0;
            if(L<=m)ans=max(ans,querymay(id,L,R,ls));
            if(m<R)ans=max(ans,querymay(id,L,R,rs));
            return ans;
        }
        int querymax(int xl,int xr,int yl,int yr,int l,int r,int rt)
        {
            if(xl<=l&&r<=xr){return querymay(rt,yl,yr,1,n,1);}
            int m=(l+r)>>1,ans=0;
            if(xl<=m)ans=max(ans,querymax(xl,xr,yl,yr,ls));
            if(m<xr)ans=max(ans,querymax(xl,xr,yl,yr,rs));
            return ans;
        }
        int querymiy(int id,int L,int R,int l,int r,int rt)
        {
            if(L<=l&&r<=R)return mi[id][rt];
            int m=(l+r)>>1,ans=1e9+10;
            if(L<=m)ans=min(ans,querymiy(id,L,R,ls));
            if(m<R)ans=min(ans,querymiy(id,L,R,rs));
            return ans;
        }
        int querymix(int xl,int xr,int yl,int yr,int l,int r,int rt)
        {
            if(xl<=l&&r<=xr)return querymiy(rt,yl,yr,1,n,1);
            int m=(l+r)>>1,ans=1e9+10;
            if(xl<=m)ans=min(ans,querymix(xl,xr,yl,yr,ls));
            if(m<xr)ans=min(ans,querymix(xl,xr,yl,yr,rs));
            return ans;
        }
        int query(int x,int y,int l)
        {
            int xl=max(1,x-l/2),xr=min(n,x+l/2);
            int yl=max(1,y-l/2),yr=min(n,y+l/2);
            int ma=querymax(xl,xr,yl,yr,1,n,1);
            int mi=querymix(xl,xr,yl,yr,1,n,1);
    //        printf("%d %d
    ",ma,mi);
            int ans=floor(1.0*(ma+mi)/2);
            updatex(x,y,ans,1,n,1);
            return ans;
        }
        void debug(int id,int l,int r,int rt)
        {
            printf("%d %d %d %d
    ",l,r,ma[id][rt],mi[id][rt]);
            if(l==r)return ;
            int m=(l+r)>>1;
            debug(id,ls);debug(id,rs);
        }
    }s;
    int main()
    {
        int T,cnt=0;scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    scanf("%d",&c[i][j]);
            s.buildx(1,n,1,1,n);
    //        s.debug(5,1,n,1);
            int q;scanf("%d",&q);
            printf("Case #%d:
    ",++cnt);
            while(q--)
            {
                int x,y,l;
                scanf("%d%d%d",&x,&y,&l);
                printf("%d
    ",s.query(x,y,l));
            }
        }
        return 0;
    }
    /***********************
    1
    3
    1 2 3
    4 5 6
    7 8 9
    5
    2 2 1
    ***********************/
    View Code
  • 相关阅读:
    C#中使用事务
    C#中执行数据库存储过程
    构建ASP.net的AJAX开发环境
    C#开发数据库技巧汇总
    索引的作用及其使用
    C#中的多态性
    C#中调用C++的DLL
    不借助其它变量交换两变量值
    ASP.NET页面间传值的9种方式
    TERSUS无代码开发(笔记11)TERSUS框架学习框架基本信息修改
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8996936.html
Copyright © 2020-2023  润新知