• CodeChef


    Read problems statements in Mandarin Chinese and Russian.

    A meteor fell on Andrew's house. That's why he decided to build a new home and chose a site where he wanted to build it. Let the whole area be a rectangular field of size NxM. Naturally, Andrew wanted to build a house on the entire area of the site. However, the Hazardous Construction Prevention Bureau did not let Andrew's plans come true. The Bureau said that some of the cells of the field are dangerous for the foundation. There are exactly K such cells.

    Andrew's not a poor man. And as anyone who has money, he saves money. Therefore, he is willing to buy not the whole area, but only a stripe of the same width. The house will occupy a rectangular area in this stripe with sides parallel to the sides of the original site.

    Andrew is asking for your help: for each LiHi - the lowest and the highest boundaries (inclusive), respectively - find the maximum area of ​​the house that Andrew can build on the relevant site.

    Input

    In the first line you are given three integers NM and K.
    In the following K lines you are given different pairs of integers xiyi - the coordinates of the dangerous cells.
    Next line contains an integer Q - the number of Andrew's queries
    The last Q lines describe the queries: each line contains two integers L and H - the lowest and the highest boundaries.

    Output

    In the output file, print Q lines, where i-th line contains the answer for i-th query. If you cannot build the house, then output 0.

    Constraints

    • 1 ≤ N, M ≤ 1000
    • 1 ≤ K ≤ N * M
    • 1 ≤ xi ≤ N
    • 1 ≤ yi ≤ M
    • 1 ≤ Q ≤ 106
    • 1 ≤ Li ≤ Hi ≤ N

    Example

    Input:
    4 5 5
    2 1
    3 2
    1 3
    2 4
    1 4
    4
    1 1
    3 4
    2 3
    1 4
    
    Output:
    2
    6
    3
    6


    发现询问数过于多了,因为最多的行区间不过10^6,所以我们可以先预处理出所有区间的答案然后O(1)回答询问。
    设f[i][j] 为第i~j行的最大矩阵面积,也就是题目所求。然后再设g[i][j]为 上边界是i,下边界是j的矩阵最宽可以是多少。
    于是转移很好写 => f[i][j] = max{f[i+1][j] , f[i][j-1] , g[i][j] * (j-i+1)}.所以现在关键是怎么求 g[i][j]。
    考虑单调栈求一个二维最大全1矩形的做法,我们可以扩展一下: 加入当前扫到的下边界在i,然后对于从左到右的每一个点j,它向上的高度是h[j],并且
    向左右最多能延伸的位置是 L[j],R[j],这个时候我们就可以用 R[j]-L[j]+1去更新 g[i-h[j]+1 ~ i][i]。
    当然不能暴力更新,打个标记之后就是O(N^2)的了,,再加上算f也是O(N^2)的,就可以愉快的A了本题了23333

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1005;
    int F[maxn][maxn],G[maxn][maxn];
    int n,m,Q,PX,PY,num,s[maxn],tp;
    int L[maxn],R[maxn],h[maxn];
    bool v[maxn][maxn];
    
    inline int read(){
    	int x=0; char ch=getchar();
    	for(;!isdigit(ch);ch=getchar());
    	for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    	return x;
    }
    
    inline void init(){
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++)
    		    if(v[i][j]) h[j]=0;
    		    else h[j]++;
    		
    		s[tp=0]=0;
    		for(int j=1;j<=m;j++){
    			while(tp&&h[s[tp]]>=h[j]) tp--;
    			L[j]=s[tp],s[++tp]=j;
    		}
    		s[tp=0]=m+1;
    		for(int j=m;j;j--){
    			while(tp&&h[s[tp]]>=h[j]) tp--;
    			R[j]=s[tp],s[++tp]=j;
    		}
    		
    		for(int j=1;j<=m;j++) G[i][i-h[j]+1]=max(G[i][i-h[j]+1],R[j]-L[j]-1);
    		
    		for(int j=1;j<=i;j++) G[i][j]=max(G[i][j],G[i][j-1]);
    	}
    	
    	for(int i=1;i<=n;i++) F[i][i]=G[i][i];
    	
    	for(int len=1;len<n;len++)
    	    for(int i=1,j=i+len;j<=n;j++,i++) F[j][i]=max(max(F[j-1][i],F[j][i+1]),G[j][i]*(j-i+1));
    }
    
    inline void solve(){
    	Q=read();
    	while(Q--){
    		PX=read(),PY=read();
    		printf("%d
    ",F[PY][PX]);
    	}
    }
    
    int main(){
    	scanf("%d%d%d",&n,&m,&num);
    	for(int i=1;i<=num;i++){
    		PX=read(),PY=read();
    		v[PX][PY]=1;
    	}
    	
    	init();
    	solve();
    	
    	return 0;
    }
    

      

     
  • 相关阅读:
    微博CacheService架构浅析 对底层协议进行适配
    Lucene 查询原理 传统二级索引方案 倒排链合并 倒排索引 跳表 位图
    Linux kernel 同步机制
    对话 CTO〡用声音在一起,听荔枝 CTO 丁宁聊 UGC 声音互动平台的技术世界 原创 王颖奇 极客公园 2018-12-01
    当中台遇上DDD,我们该如何设计微服务?
    京东技术沙龙系列之二 | 深度解析京东微服务组件平台
    gRPC设计动机和原则
    微信全文搜索优化之路
    门户级UGC系统的技术进化路线——新浪新闻评论系统的架构演进和经验总结 提高响应性能的手段归根结底就是三板斧:队列(Queue)、缓存(Cache)和分区(Sharding)
    现加减乘除4则运算
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8849148.html
Copyright © 2020-2023  润新知