zoukankan      html  css  js  c++  java
  • 二维单调队列或st表

    模板题 :[HAOI2007]理想的正方形
    题目链接:https://www.luogu.com.cn/problem/P2216
    二维st表或二维单调队列。
    单调队列做法:
    Code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e3+10;
    int a,b,n,num[N][N],q[N],fnmx[N][N],fnmn[N][N];
    int datmin[N][N],datmax[N][N],fucker[N],ans=INT_MAX;
    void solve1(int x){
    	int l=1,r=0,*c=num[x];
    	for(int i=1;i<=b;i++){
    		while(l<=r&&c[i]<c[q[r]])r--;
    		q[++r]=i;
    		while(l<=r&&i-q[l]>=n)l++;
    		if(i>=n)datmin[x][i]=c[q[l]];
    	} 
    	return;
    }
    void solve2(int x){
    	int l=1,r=0,*c=num[x];
    	for(int i=1;i<=b;i++){
    		while(l<=r&&c[i]>c[q[r]])r--;
    		q[++r]=i;
    		while(l<=r&&i-q[l]>=n)l++;
    		if(i>=n)datmax[x][i]=c[q[l]];
    	}
    	return;
    }
    void solve3(int x){
    	int l=1,r=0;
    	for(int i=1;i<=a;i++)
    		fucker[i]=datmax[i][x];
    	for(int i=1;i<=a;i++){
    		while(l<=r&&fucker[i]>fucker[q[r]])r--;
    		while(l<=r&&i-q[l]>=n)l++;
    		q[++r]=i;
    		if(i>=n)fnmx[i][x]=fucker[q[l]];
    	}
    	return;	
    }
    void solve4(int x){
    	int l=1,r=0;
    	for(int i=1;i<=a;i++)
    		fucker[i]=datmin[i][x];
    	for(int i=1;i<=a;i++){
    		while(l<=r&&fucker[i]<fucker[q[r]])r--;
    		while(l<=r&&i-q[l]>=n)l++;
    		q[++r]=i;
    		if(i>=n)fnmn[i][x]=fucker[q[l]];
    	}
    	return;	
    } 
    int main(){
    	scanf("%d%d%d",&a,&b,&n);
    	for(int i=1;i<=a;i++)
    		for(int j=1;j<=b;j++)
    			scanf("%d",&num[i][j]);
    	for(int i=1;i<=a;i++)solve1(i),solve2(i);
    	for(int i=b;i>=n;i--)solve3(i),solve4(i);
    	for(int i=1;i<=a;i++)
    		for(int j=1;j<=b;j++)
    			if(fnmx[i][j]&&fnmn[i][j])ans=min(fnmx[i][j]-fnmn[i][j],ans);
    	printf("%d",ans);
    	return 0;
    }
    

    二维st表:

    #include<bits/stdc++.h>
    using namespace std;
    const int INF=2147483647,N=1e3+5;
    int n,m,k,K,grid[N][N],dv[N][N],xv[N][N];
    int query(int x, int y){
        int mx=0,mn=0;
        mx=max(dv[x][y],max(dv[x+k-(1<<K)][y+k-(1<<K)],max(dv[x+k-(1<<K)][y],dv[x][y+k-(1<<K)])));
        mn=min(xv[x][y],min(xv[x+k-(1<<K)][y+k-(1<<K)],min(xv[x+k-(1<<K)][y],xv[x][y+k-(1<<K)])));
        return mx-mn;
    }
    int main (){
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                scanf("%d",&grid[i][j]);
                dv[i][j]=xv[i][j]=grid[i][j];
            }    	
    	K=floor(log2(k));
        for(int s=0;s<=K-1;s++)
            for(int i=1;i+(1<<s)<=n;i++)
                for(int j=1;j+(1<<s)<=m;j++){
                    dv[i][j]=max(dv[i][j],max(dv[i+(1<<s)][j+(1<<s)],max(dv[i+(1<<s)][j],dv[i][j+(1<<s)])));
                    xv[i][j]=min(xv[i][j],min(xv[i+(1<<s)][j+(1<<s)],min(xv[i+(1<<s)][j],xv[i][j+(1<<s)])));	
    	        }
        int ans=INF;
        for(int i=1;i<=n-k+1;i++)
            for(int j=1;j<=m-k+1;j++)ans=min(ans,query(i,j));
    	printf("%d\n",ans);
        return 0;
    }
    
  • 相关阅读:
    【转】C#中Serializable序列化实例详解
    【转】c# [Serializable]的作用
    【转】垂直分库和水平分库
    js数组歌
    好用的漂浮广告 jquery
    详解Vue 开发模式下跨域问题
    老项目用webpack中文乱码问题解决记录
    Vuex异步请求数据通过computed计算属性值
    js数组操作
    Vuex速学篇:(2)利用state保存新闻数据
  • 原文地址:https://www.cnblogs.com/Xxhdjr/p/13419580.html
Copyright © 2011-2022 走看看