Submission #1052395

# Submission time Handle Problem Language Result Execution time Memory
1052395 2024-08-10T14:15:02 Z _rain_ 3D Histogram (COCI20_histogram) C++14
20 / 110
2500 ms 45916 KB
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
 
template<class T1 , class T2>
	bool maximize(T1& a , T2 b)
	{
		if (a < b) return a = b , true;
		return false;
	}
template<class T1 , class T2>
	bool minimize(T1& a , T2 b)
	{
		if (a > b) return a = b , true;
		return false;
	}
 
const int maxn = 2e5;
 
//... CONVEXHULL
	#define sz(x) (x).size()
	struct Line
	{
	    i64 a , b;
	    Line(i64 a , i64 b) : a(a) , b(b) {};
	};
	struct Hull
	{   
	    Line X;
	    long double intersec;
	};

	class Convexhull
	{
	    public:
	        vector<Hull> line;
	        long double getintersec(Line x , Line y)
	        {
	            return (long double)(y.b - x.b) / (x.a - y.a);
	        }
	        i64 getval(Line a , i64 x)
	        {
	            return a.a * x + a.b;
	        }
	        void addline(Line a)
	        {
	            int n = sz(line);
	            while (n > 1 && getintersec(line[n - 2].X , a) <= getintersec(line[n - 1].X , line[n - 2].X))
	                line.pop_back() , --n;
	            if (!sz(line))
	                line.push_back({a , LLONG_MIN });
	            else line.push_back({a , getintersec(a , line[n - 1].X)});
	            return;
	        }
	        i64 find(i64 val)
	        {
	            int low = 0 , high = sz(line) - 1 , p = 0;
	            while (low <= high)
	            {
	                int mid = low + high >> 1;
	                if (line[mid].intersec <= val) p = mid , low = mid + 1;
	                    else high = mid - 1;
	            }
	            return getval(line[p].X , val) ;
	        }
	        void add(i64 a , i64 b)
	        {
	            addline(Line{a , b});
	            return;
	        }
	        void reset()
	        {
	        	line.clear();
	        }
	};
	Convexhull operator + (Convexhull a , Convexhull b)
	{
		Convexhull c;
		int id1 = 0 , id2 = 0;
		for (; id1 < a.line.size() && id2 < b.line.size() ; )
		{
			if (a.line[id1].X.a < b.line[id2].X.a)
			{
				c.addline(a.line[id1++].X);
			}
			else {
				c.addline(b.line[id2++].X);
			}
		}
		for (; id1 < a.line.size(); ++id1) c.addline(a.line[id1].X);
		for (; id2 < b.line.size(); ++id2) c.addline(b.line[id2].X);
		return c;
	}

const i64 INF = 1e18 + 7;
int n;
i64 a[maxn+2],b[maxn+2];
i64 mnA[maxn+2][2] , mnB[maxn+2][2];
 

//... BUILD SEGMENT_TREE
	Convexhull stA[maxn*4+2];
	Convexhull stB[maxn*4+2];

	void buildA(int id , int l , int r , int u , int v)
	{
		stA[id].reset();
		if (l > v || r < u) return;
		if (l==r)
		{
			stA[id].add(-mnA[l][1] , mnA[l][1] * (l+1));
			return;
		}
		else {
			int m = l + r >> 1;
			buildA(id*2,l,m,u,v);
			buildA(id*2+1,m+1,r,u,v);
			stA[id] = stA[id*2] + stA[id*2+1];
			return;
		}
	}
	void buildB(int id , int l , int r , int u , int v)
	{
		stB[id].reset();
		if (l > v || r < u) return ;
		if (l==r)
		{
			stB[id].add(-mnB[l][1] , mnB[l][1] * (l+1));
			return;
		}
		else {
			int m = l + r >> 1;
			buildB(id*2,l,m,u,v);
			buildB(id*2+1,m+1,r,u,v);
			stB[id] = stB[id*2] + stB[id*2+1];
			return;
		}
	}
	i64 getA(int id , int l , int r , int u , int v , i64 k)
	{
		if (l > v || r < u) return -INF;
		if (u <= l && r <= v) return stA[id].find(k);
		int m = l + r >> 1;
		return max(getA(id*2,l,m,u,v,k),getA(id*2+1,m+1,r,u,v,k));
	}
	i64 getB(int id , int l , int r , int u , int v , i64 k)
	{
		if (l > v || r < u) return -INF;
		if (u <= l && r <= v) return stB[id].find(k);
		int m = l + r >> 1;
		return max(getB(id*2,l,m,u,v,k),getB(id*2+1,m+1,r,u,v,k));
	}
//...;

void build_LEFT(int l , int r)
{
	mnA[r+1][0] = mnB[r+1][0] = INF;
	for (int i = r; i >= l; --i)
	{
		mnA[i][0]=min(mnA[i+1][0],a[i]);
		mnB[i][0]=min(mnB[i+1][0],b[i]);
	}
	return;
}
void build_RIGHT(int l , int r)
{
	mnA[l-1][1] = mnB[l-1][1] = INF;
	for (int i = l; i <= r; ++i)
	{
		mnA[i][1]=min(mnA[i-1][1],a[i]);
		mnB[i][1]=min(mnA[i-1][1],b[i]);
	}
	buildA(1,1,n,l,r);
	buildB(1,1,n,l,r);
	return; 
}

i64 case1(int l , int m , int r) // LEFT IS MINA , RIGHT IS MINB
{
	i64 res = 0;
	int j = r;
	for (int i = m; i >= l; --i)
	{
		while (j > m && mnA[j][1] < mnA[i][0]) --j;
		int low = m + 1 , high = j , pos = -1;
		while (low <= high)
				{
					int mid = low + high >> 1;
					if (mnB[i][0] >= mnB[mid][1])
					{
						pos = mid;
						high = mid - 1;
					}
					else low = mid + 1;
				}
		// cout<<'('<<i<<"->"<<pos<<','<<j<<')'<<'\n';
		if (pos == -1) continue;
		i64 x = getB(1,1,n,pos,j,i);
		// cout<<'('<<i<<','<<" ||| "<<pos<<'-'<<j<<" || "<<x<<')'<<'\n';
		if (x < 0) continue;
		res = max(res , x * mnA[i][0]);
	}
	return res;
}
i64 case2(int l , int m , int r) // LEFT IS MINB , RIGHT IS MINA
{
	i64 res = 0;
	int j = r;
	for (int i = m; i >= l; --i)
	{
		while (j > m && mnB[j][1] < mnB[i][0]) --j;
		int low = m + 1 , high = j , pos = -1;
		while (low <= high)
				{
					int mid = low + high >> 1;
					if (mnA[i][0] >= mnA[mid][1])
					{
						pos = mid;
						high = mid - 1;
					}
					else low = mid + 1;
				}
		// cout<<'('<<i<<"->"<<pos<<','<<j<<')'<<'\n';
		if (pos == -1) continue;
		i64 x = getA(1,1,n,pos,j,i);
		// cout<<'('<<i<<','<<" ||| "<<pos<<'-'<<j<<" || "<<x<<')'<<'\n';
		if (x < 0) continue;
		res = max(res , x * mnB[i][0]);
	}
	return res;
}
 
i64 solve(int l , int r)
{
	if (l > r) return 0;
	if (l==r) return a[l]*b[l];

	int m = l + r >> 1;
	build_LEFT(l,m);
	build_RIGHT(m+1,r);
	i64 res = 0;
	// cout << "CASE : " << l <<','<<m<<','<<r<<'\n';

	res = max(res , case1(l,m,r));
	res = max(res , case2(l,m,r));
	res = max({res , solve(l,m), solve(m+1,r)});
	return res;
}
 
int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	#define name "main"
	if (fopen(name".inp","r"))
	{
		(void)freopen(name".inp","r",stdin);
		(void)freopen(name".out","w",stdout);
	}
	cin >> n;
	for (int i = 1; i <= n; ++i) cin >> a[i] >> b[i];
	// for (int i = 1; i <= n; ++i) cout << a[i] << ' ' << b[i] << '\n';
	i64 res = 0;
	for (int i = 1; i <= n; ++i)
	{
		i64 mx = a[i] , mn = b[i];
		for (int j = i; j >= 1; --j)
		{
			mx = min(mx , a[j]);
			mn = min(mn , b[j]);
			res = max(res , mx * mn * (i - j + 1));
		}
	}
	cout << res;
}

Compilation message

histogram.cpp: In member function 'i64 Convexhull::find(i64)':
histogram.cpp:60:32: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   60 |                  int mid = low + high >> 1;
      |                            ~~~~^~~~~~
histogram.cpp: In function 'Convexhull operator+(Convexhull, Convexhull)':
histogram.cpp:80:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Hull>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   80 |   for (; id1 < a.line.size() && id2 < b.line.size() ; )
      |          ~~~~^~~~~~~~~~~~~~~
histogram.cpp:80:37: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Hull>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   80 |   for (; id1 < a.line.size() && id2 < b.line.size() ; )
      |                                 ~~~~^~~~~~~~~~~~~~~
histogram.cpp:90:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Hull>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   90 |   for (; id1 < a.line.size(); ++id1) c.addline(a.line[id1].X);
      |          ~~~~^~~~~~~~~~~~~~~
histogram.cpp:91:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Hull>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   91 |   for (; id2 < b.line.size(); ++id2) c.addline(b.line[id2].X);
      |          ~~~~^~~~~~~~~~~~~~~
histogram.cpp: In function 'void buildA(int, int, int, int, int)':
histogram.cpp:115:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  115 |    int m = l + r >> 1;
      |            ~~^~~
histogram.cpp: In function 'void buildB(int, int, int, int, int)':
histogram.cpp:132:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  132 |    int m = l + r >> 1;
      |            ~~^~~
histogram.cpp: In function 'i64 getA(int, int, int, int, int, i64)':
histogram.cpp:143:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  143 |   int m = l + r >> 1;
      |           ~~^~~
histogram.cpp: In function 'i64 getB(int, int, int, int, int, i64)':
histogram.cpp:150:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  150 |   int m = l + r >> 1;
      |           ~~^~~
histogram.cpp: In function 'i64 case1(int, int, int)':
histogram.cpp:188:20: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  188 |      int mid = low + high >> 1;
      |                ~~~~^~~~~~
histogram.cpp: In function 'i64 case2(int, int, int)':
histogram.cpp:215:20: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  215 |      int mid = low + high >> 1;
      |                ~~~~^~~~~~
histogram.cpp: In function 'i64 solve(int, int)':
histogram.cpp:238:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  238 |  int m = l + r >> 1;
      |          ~~^~~
histogram.cpp: In function 'int main()':
histogram.cpp:257:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  257 |   (void)freopen(name".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
histogram.cpp:258:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  258 |   (void)freopen(name".out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 9 ms 41560 KB Output is correct
2 Correct 9 ms 41564 KB Output is correct
3 Correct 8 ms 41680 KB Output is correct
4 Correct 9 ms 41564 KB Output is correct
5 Correct 8 ms 41560 KB Output is correct
6 Correct 8 ms 41564 KB Output is correct
7 Correct 8 ms 41564 KB Output is correct
8 Correct 10 ms 41560 KB Output is correct
9 Correct 8 ms 41564 KB Output is correct
10 Correct 8 ms 41564 KB Output is correct
11 Correct 6 ms 41564 KB Output is correct
12 Correct 9 ms 41716 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 9 ms 41560 KB Output is correct
2 Correct 9 ms 41564 KB Output is correct
3 Correct 8 ms 41680 KB Output is correct
4 Correct 9 ms 41564 KB Output is correct
5 Correct 8 ms 41560 KB Output is correct
6 Correct 8 ms 41564 KB Output is correct
7 Correct 8 ms 41564 KB Output is correct
8 Correct 10 ms 41560 KB Output is correct
9 Correct 8 ms 41564 KB Output is correct
10 Correct 8 ms 41564 KB Output is correct
11 Correct 6 ms 41564 KB Output is correct
12 Correct 9 ms 41716 KB Output is correct
13 Execution timed out 2564 ms 45916 KB Time limit exceeded
14 Halted 0 ms 0 KB -