• [bzoj1047][HAOI2007]理想的正方形


    给定r,c,n和一个r行c列的矩阵,你需要找到一个n*n的矩形,使得其中的最大值和最小值的差最小 r,c<=1000

    题解:

    看情况乱搞 

    线段树先横着查一下每个点后m个的最值,然后竖着搞一遍。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 1024
    #define INF 2000000000
    using namespace std;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    int s[1005][1005],s2[1005][1005];
    int T[N*2+5],T2[N*2+5];
    int n,m,c,ans=INF;
    int num[1005][1005];
    
    int query2(int l,int r)
    {
        int sum=INF;
        for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
        {
            if(~l&1)sum=min(sum,T2[l+1]);
            if( r&1)sum=min(sum,T2[r-1]);
        }
        return sum;
    }
    
    int query1(int l,int r)
    {
        int sum=0;
        for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
        {
            if(~l&1)sum=max(sum,T[l+1]);
            if( r&1)sum=max(sum,T[r-1]);
        }
        return sum;
    }
    
    void renew1(int x,int ad)
    {
        T[x+=N]=ad;
        for(x>>=1;x;x>>=1) T[x]=max(T[x<<1],T[(x<<1)+1]);
    }
    
    void renew2(int x,int ad)
    {
        T2[x+=N]=ad;
        for(x>>=1;x;x>>=1) T2[x]=min(T2[x<<1],T2[(x<<1)+1]);
    }
    
    int main()
    {
        n=read();m=read();c=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                num[i][j]=read();
        for(int i=1;i<=n;i++)
        {
            memset(T,0,sizeof(T));for(int ii=1;ii<=2*N+1;ii++)T2[ii]=INF;
            for(int j=m;j;j--) 
            {
                renew1(j,num[i][j]);renew2(j,num[i][j]);
                if(j+c-1<=m)
                s[i][j]=query1(j,j+c-1),s2[i][j]=query2(j,j+c-1);    
            }
        }
        //for(int i=1;i<=n;i++) for(int j=1;j+c-1<=m;j++) cout<<i<<" "<<j<<" "<<s[i][j]<<" "<<s2[i][j]<<endl;
        for(int i=1;i+c-1<=m;i++)
        {
            memset(T,0,sizeof(T));for(int ii=1;ii<=2*N+1;ii++)T2[ii]=INF;
            for(int j=n;j;j--)
            {
                renew1(j,s[j][i]);renew2(j,s2[j][i]);
                if(j+c-1<=n) ans=min(ans,query1(j,j+c-1)-query2(j,j+c-1));
            }
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    DataGrip for Mac破解步骤详解 亲测好用
    git 之路
    linux用户管理
    virtualenvwrappers pipreqs 踩坑
    pycharm 快捷键
    kubernetes(k8s)之K8s部署多种服务yaml文件
    centos下彻底删除mysql的方法
    vi 和vim 的区别
    Django中related_name作用
    Windows CMD命令大全
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj1047.html
Copyright © 2020-2023  润新知