Cod sursa(job #593705)

Utilizator darrenRares Buhai darren Data 4 iunie 2011 12:11:48
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.64 kb
 #include <fstream>
 #include <deque>
 
 using namespace std;
 
 int N, M, P;
 int A[1002][1002];
 deque<int> Dmin[1002];
 deque<int> Dmax[1002];
 deque<int> Rmin;
 deque<int> Rmax;
 
 int main()
 {
	ifstream fin("struti.in");
	ofstream fout("struti.out");
	
	fin >> N >> M >> P;
	for (int i = 1; i <= N; ++i)
		for (int j = 1; j <= M; ++j)
			fin >> A[i][j];
	
	int L1, L2;
	for (int k = 1; k <= P; ++k)
	{
		fin >> L1 >> L2;
		int minnow = 1 << 30, total = 0;
		
		for (int i = 1; i <= M; ++i)
		{
			Dmin[i].clear();
			Dmax[i].clear();
		}
		for (int i = 1; i <= N; ++i)
		{
			for (int j = 1; j <= M; ++j)
			{
				if (!Dmin[j].empty() && Dmin[j].front() <= i - L1)
					Dmin[j].pop_front();
				while (!Dmin[j].empty() && A[i][j] <= A[Dmin[j].back()][j])
					Dmin[j].pop_back();
				Dmin[j].push_back(i);
				
				if (!Dmax[j].empty() && Dmax[j].front() <= i - L1)
					Dmax[j].pop_front();
				while (!Dmax[j].empty() && A[i][j] >= A[Dmax[j].back()][j])
					Dmax[j].pop_back();
				Dmax[j].push_back(i);
			}
			
			if (i < L1) continue;
			
			Rmin.clear();
			Rmax.clear();
			
			for (int j = 1; j <= M; ++j)
			{
				if (!Rmin.empty() && Rmin.front() <= j - L2)
					Rmin.pop_front();
				while (!Rmin.empty() && A[Dmin[j].front()][j] <= A[Dmin[Rmin.back()].front()][Rmin.back()])
					Rmin.pop_back();
				Rmin.push_back(j);
				
				if (!Rmax.empty() && Rmax.front() <= j - L2)
					Rmax.pop_front();
				while (!Rmax.empty() && A[Dmax[j].front()][j] >= A[Dmax[Rmax.back()].front()][Rmax.back()])
					Rmax.pop_back();
				Rmax.push_back(j);
				
				if (j >= L2)
					if (A[Dmax[Rmax.front()].front()][Rmax.front()] - A[Dmin[Rmin.front()].front()][Rmin.front()] < minnow)
					{
						minnow = A[Dmax[Rmax.front()].front()][Rmax.front()] - A[Dmin[Rmin.front()].front()][Rmin.front()];
						total = 1;
					}
					else if (A[Dmax[Rmax.front()].front()][Rmax.front()] - A[Dmin[Rmin.front()].front()][Rmin.front()] == minnow)
						++total;
			}
		}
		
		
		for (int i = 1; i <= M; ++i)
		{
			Dmin[i].clear();
			Dmax[i].clear();
		}
		for (int i = 1; i <= N; ++i)
		{
			for (int j = 1; j <= M; ++j)
			{
				if (!Dmin[j].empty() && Dmin[j].front() <= i - L2)
					Dmin[j].pop_front();
				while (!Dmin[j].empty() && A[i][j] <= A[Dmin[j].back()][j])
					Dmin[j].pop_back();
				Dmin[j].push_back(i);
				
				if (!Dmax[j].empty() && Dmax[j].front() <= i - L2)
					Dmax[j].pop_front();
				while (!Dmax[j].empty() && A[i][j] >= A[Dmax[j].back()][j])
					Dmax[j].pop_back();
				Dmax[j].push_back(i);
			}
			
			if (i < L2) continue;
			
			Rmin.clear();
			Rmax.clear();
			
			for (int j = 1; j <= M; ++j)
			{
				if (!Rmin.empty() && Rmin.front() <= j - L1)
					Rmin.pop_front();
				while (!Rmin.empty() && A[Dmin[j].front()][j] <= A[Dmin[Rmin.back()].front()][Rmin.back()])
					Rmin.pop_back();
				Rmin.push_back(j);
				
				if (!Rmax.empty() && Rmax.front() <= j - L1)
					Rmax.pop_front();
				while (!Rmax.empty() && A[Dmax[j].front()][j] >= A[Dmax[Rmax.back()].front()][Rmax.back()])
					Rmax.pop_back();
				Rmax.push_back(j);
				
				if (j >= L1)
					if (A[Dmax[Rmax.front()].front()][Rmax.front()] - A[Dmin[Rmin.front()].front()][Rmin.front()] < minnow)
					{
						minnow = A[Dmax[Rmax.front()].front()][Rmax.front()] - A[Dmin[Rmin.front()].front()][Rmin.front()];
						total = 1;
					}
					else if (A[Dmax[Rmax.front()].front()][Rmax.front()] - A[Dmin[Rmin.front()].front()][Rmin.front()] == minnow)
						++total;
			}
		}
		
		if (L1 == L2) total /= 2;
		fout << minnow << ' ' << total << '\n';
		
	}
	
	fin.close();
	fout.close();
 }