Submission #129054

#TimeUsernameProblemLanguageResultExecution timeMemory
129054LawlietHoliday (IOI14_holiday)C++14
7 / 100
343 ms65536 KiB
#include <bits/stdc++.h>

#define MAX 100010
#define MAXV 1000000010

using namespace std;
typedef long long int lli;

class PersistentSegmentTree
{
	public:

		void copy(int node)
		{
			e.push_back( e[node] );
			d.push_back( d[node] );

			qtd.push_back( qtd[node] );

			sum.push_back( sum[node] );
		}

		int update(int node, int l, int r, int i)
		{
			int newNode = ++curNode;
			copy( node );

			if(l == r)
			{
				qtd[newNode]++;
				sum[newNode] += i;

				return newNode;
			}

			int m = (l + r)/2;

			if(i <= m)
			{
				int aux = update(e[newNode] , l , m , i);
				e[newNode] = aux;
			}
			else
			{
				int aux = update(d[newNode] , m + 1 , r , i);
				d[newNode] = aux;
			}

			qtd[newNode] = qtd[ e[newNode] ] + qtd[ d[newNode] ];
			sum[newNode] = sum[ e[newNode] ] + sum[ d[newNode] ];

			return newNode;
		}

		lli bs(int nodeL, int nodeR, int l, int r, lli k)
		{
			if(l == r) return k*l;

			int m = (l + r)/2;

			int qtdRight = qtd[ d[nodeR] ] - qtd[ d[nodeL] ];
			lli sumRight = sum[ d[nodeR] ] - sum[ d[nodeL] ];

			if(k <= qtdRight) return bs(d[nodeL] , d[nodeR] , m + 1 , r , k);
			return bs(e[nodeL] , e[nodeR] , l , m , k - qtdRight) + sumRight;
		}

		lli getHighests(int l, int r, int k)
		{
			if(k == 0) return 0;

			return bs(root[l - 1] , root[r] , 0 , MAXV , k);
		}

		void update(int v)
		{
			curVersion++;

			root[curVersion] = update(root[curVersion - 1] , 0 , MAXV , v);
		}

		void init()
		{
			e.clear(); d.clear();
			qtd.clear(); sum.clear();

			e.push_back( 0 ); d.push_back( 0 );
			qtd.push_back( 0 ); sum.push_back( 0LL );

			copy( 0 );

			root[0] = 1;

			curNode = 1;
			curVersion = 0;
		}

	private:

		int curNode;
		int curVersion;

		int root[MAX];

		vector<int> e, d;
		vector<int> qtd;

		vector<lli> sum;
};

int N, S, D;

lli ans;

PersistentSegmentTree SEG;

void DivAndConquer(int l, int r, int optmin, int optmax)
{
	if(l > r) return;

	int mid = (l + r)/2;

	int optInd;
	lli optAns = -1;

	for(int g = optmin ; g <= optmax ; g++)
	{
		int walkDays = (S - mid) + (g - mid);

		if(walkDays < 0) continue;

		lli curAns = SEG.getHighests(mid , g , D - walkDays);

		if(curAns > optAns)
		{
			optInd = g;
			optAns = curAns;
		}
	}

	ans = max(ans , optAns);

	DivAndConquer(l , mid - 1 , optmin , optInd);
	DivAndConquer(mid + 1 , r , optInd , optmax);
}

long long int findMaxAttraction(int n, int start, int d, int attraction[])
{
	N = n; S = start + 1; D = d;

	lli mx = -1;

	SEG.init();

	for(int g = 0 ; g < n ; g++)
		SEG.update( attraction[g] );

	DivAndConquer(1 , S , S , N);

	SEG.init();

	for(int g = n - 1 ; g >= 0 ; g--)
		SEG.update( attraction[g] );

	S = N - S + 1;

	DivAndConquer(1 , S , S , N);

	return ans;
}

Compilation message (stderr)

holiday.cpp: In function 'long long int findMaxAttraction(int, int, int, int*)':
holiday.cpp:151:6: warning: unused variable 'mx' [-Wunused-variable]
  lli mx = -1;
      ^~
holiday.cpp: In function 'void DivAndConquer(int, int, int, int)':
holiday.cpp:143:15: warning: 'optInd' may be used uninitialized in this function [-Wmaybe-uninitialized]
  DivAndConquer(l , mid - 1 , optmin , optInd);
  ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...