zoukankan      html  css  js  c++  java
  • zoj 2859 RMQ问题 使用分割法求解

    把整个矩阵按sqrt(n)为一块,分成n/sqrt(n)块,在查询的时候就按照小块进行分割。边缘部分按照顺时针分成相同的小条。

    边

    代码如下:

    /*The solution of RMQ using a <O(n), O(sqrt(n))> algrithom
     *http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor
     */
    #include <stdio.h>
    
    #define min(a,b) (((a)<(b))?(a):(b))
    #define N 310
    
    int matrix[N][N];
    int M[17][17];
    
    int mysqrt(int n)
    {
    	int pos = 0, i = 0;
    	while(i <= n)
    	{
    		if( (pos+1)*(pos+1) == i)
    			pos += 1;
    		i++;
    	}
    	return pos;
    }
    
    int minMatrix(int choose, int i, int j, int u, int v)
    {
    	int k, t;
    	int min;
    	int flag = 0;
    
    	switch(choose)
    	{
    	case 1:
    		min = matrix[i][j];
    		for(k = i; k <= u; k++)
    			for(t = j; t <= v; t++)
    			{
    				flag = 1;
    				if(matrix[k][t] < min)
    					min = matrix[k][t];
    			}
    		break;
    
    	case 2:
    		min = M[i][j];
    		for(k = i; k <= u; k++)
    			for(t = j; t <= v; t++)
    			{
    				flag = 1;
    				if(M[k][t] < min)
    					min = M[k][t];
    			}
    		break;
    	}
    
    	return flag?min:0x7FFFFFFF;
    }
    
    void initCUT(int n)
    {
    	int sn = mysqrt(n);
    	int block = n/sn;
    	int i, j;
    	for(i = 0; i < block; i++)
    		for(j = 0; j < block; j++)
    		{
    			M[i][j] = minMatrix(1, sn*i, sn*j, sn*(i+1)-1, sn*(j+1)-1);
    		}
    }
    
    int askCUT(int n, int r1, int c1, int r2, int c2)
    {
    	int sn = mysqrt(n);
    
    	if(r2-r1+1<2*sn || c2-c1+1<2*sn)
    	{
    		return minMatrix(1, r1, c1, r2, c2);
    	}
    
    	/*subtitle in M[][]*/
    	int a = (r1%sn == 0)?(r1/sn):(r1/sn+1),
    		b = (c1%sn == 0)?(c1/sn):(c1/sn+1),
    		c = ((r2+1)%sn == 0)?(r2/sn):(r2/sn-1),
    		d = ((c2+1)%sn == 0)?(c2/sn):(c2/sn-1);
    
    	/*subtitle in matrix[][]*/
    	int lt = a*sn,/*left top*/
    		rt = b*sn,/*right top*/
    		ld = (c+1)*sn - 1,/*left down*/
    		rd = (d+1)*sn - 1;/*rignt down*/
    
    	int min1 = minMatrix(2, a, b, c, d);
    
    	int min2 = minMatrix(1, r1, c1, lt-1, rd);
    	int min3 = minMatrix(1, r1, rd+1, ld, c2);
    	int min4 = minMatrix(1, ld+1, rt, r2, c2);
    	int min5 = minMatrix(1, lt, c1, r2, rt-1);
    
    	int min6 = min(min(min2, min3), min(min4, min5));
    
    	return min(min1, min6);
    }
    
    int main()
    {
    	int t;
    	scanf("%d", &t);
    	while(t--)
    	{
    		int n;
    		scanf("%d", &n);
    		
    		int i, j;
    		for(i = 0; i < n; i++)
    			for(j = 0; j < n; j++)
    				scanf("%d", &(matrix[i][j]));
    
    		if(n > 3)
    			initCUT(n);
    
    		int queries;
    		scanf("%d", &queries);
    		
    		while(queries--)
    		{
    			int r1, c1, r2, c2;
    			scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
    			if(n > 3)
    				printf("%d\n", askCUT(n, r1-1, c1-1, r2-1, c2-1));
    			else
    				printf("%d\n", minMatrix(1, r1-1, c1-1, r2-1, c2-1));
    		}
    	}
    
    	return 0;
    }

    参考算法:http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor

  • 相关阅读:
    handsontable-developer guide-data binding,data sources
    Android版Web服务器实现(三)HTTP响应
    Android版Web服务器实现(二)使用服务来监听HTTP请求
    HTTP协议详解(很详细)
    Android版Web服务器实现(一)HTTP协议请求头解析
    HTTP协议中Content-Length的详细解读。
    Android基于SwiFTP开源库的FTP实现(FTP匿名登录)
    Android之查看Wifi密码
    道德经与抽象、接口及框架
    JAVA中利用JNI与VS2012实现C/C++的DLL调用
  • 原文地址:https://www.cnblogs.com/wangshuo/p/1978305.html
Copyright © 2011-2022 走看看