답안 #569105

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
569105 2022-05-26T16:51:05 Z blue Fish 2 (JOI22_fish2) C++17
컴파일 오류
0 ms 0 KB
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vpii = vector<pii>;
#define sz(x) int(x.size())

int N;
vll A;

int Q;

struct group
{
	int i; //inclusive of the group, not the barrier.
	ll Asum;
	int winners;
};

struct info
{
	int l;
	int r;

	ll Asum;
	int winners;

	vector<group> pref;
	vector<group> suff;

	info()
	{
		;
	}

	info(int i)
	{
		l = r = i;
		Asum = A[i];
		winners = 1;
	}
};

void combine(info& res, const info& X, const info& Y) //!
{
	// cerr << "combine called\n";
	res.l = X.l;
	res.r = Y.r;

	res.Asum = X.Asum + Y.Asum;
	res.winners = 0;







	int Xs = sz(X.suff);

	ll Xdp[1 + Xs];
	Xdp[0] = A[X.r];
	for(int i = 1; i <= Xs; i++)
		Xdp[i] = max(Xdp[i-1], A[X.suff[i-1].i - 1] - X.suff[i-1].Asum);


	int Ys = sz(Y.pref);

	ll Ydp[1 + Ys];
	Ydp[0] = A[Y.l];
	for(int i = 1; i <= Ys; i++)
		Ydp[i] = max(Ydp[i-1], A[Y.pref[i-1].i + 1] - Y.pref[i-1].Asum);


	// cerr << "#\n";




	int XYreach[1 + Xs];
	int XXreach[1 + Xs];

	int YXreach[1 + Ys];
	int YYreach[1 + Ys];

	int xi, yi;

	yi = Ys;
	for(xi = Xs; xi >= 0; xi--)
	{
		ll currsum = (xi == Xs ? X.Asum : X.suff[xi].Asum);
		while(yi >= 0 && Ydp[yi] > currsum)
			yi--;

		ll Ygain;
		if(yi == Ys)
			Ygain = Y.Asum;
		else if(yi == -1)
			Ygain = 0;
		else
			Ygain = Y.pref[yi].Asum;

		if(xi < Xs && currsum + Ygain >= A[X.suff[xi].i - 1])
		{
			XXreach[xi] = XXreach[xi+1];
			XYreach[xi] = XYreach[xi+1];
		}
		else
		{
			XXreach[xi] = xi;
			XYreach[xi] = yi;
		}
	}
	// cerr << "#2\n";


	xi = Xs;
	for(yi = Ys; yi >= 0; yi--)
	{
		ll currsum = (yi == Ys ? Y.Asum : Y.pref[yi].Asum);
		while(xi >= 0 && Xdp[xi] > currsum)
			xi--;

		ll Xgain;
		if(xi == Xs)
			Xgain = X.Asum;
		else if(xi == -1)
			Xgain = 0;
		else
			Xgain = X.suff[xi].Asum;

		if(yi < Ys && currsum + Xgain >= A[Y.pref[yi].i + 1])
		{
			YYreach[yi] = YYreach[yi+1];
			YXreach[yi] = YXreach[yi+1];
		}
		else
		{
			YYreach[yi] = yi;
			YXreach[yi] = xi;
		}
	}


	// cerr << "#3\n";






	res.pref = X.pref;


	int pi = sz(res.pref);

	if(X.Asum < Ydp[0])
		res.pref.push_back({X.r, X.Asum, 0});

	for(int i = 0; i < sz(Y.pref); i++)
		if(A[Y.pref[i].i + 1] > Y.pref[i].Asum + X.Asum)
			res.pref.push_back({Y.pref[i].i, Y.pref[i].Asum + X.Asum, 0});



	res.suff = Y.suff;

	int si = sz(res.suff);

	if(Y.Asum < Xdp[0])
		res.suff.push_back({Y.l, Y.Asum, 0});

	for(int i = 0; i < sz(X.suff); i++)
		if(A[X.suff[i].i - 1] > X.suff[i].Asum + Y.Asum)
			res.suff.push_back({X.suff[i].i, X.suff[i].Asum + Y.Asum, 0});


	// cerr << "#4\n";

	vpii newpref, newsuff;

	for(xi = 0; xi <= Xs; xi++)
	{
		int xiwinners = (xi == Xs ? X.winners : X.suff[xi].winners);

		if(XXreach[xi] == Xs && XYreach[xi] == Ys)
			res.winners += xiwinners;
		else if(XXreach[xi] == Xs)
		{
			newpref.push_back({XYreach[xi], xiwinners});
		}
		else if(XYreach[xi] == Ys)
			newsuff.push_back({XXreach[xi], xiwinners});
	}
	// cerr << "#4-1\n";

	for(yi = 0; yi <= Ys; yi++)
	{
		// cerr << "entered : " << yi << '\n';
		int yiwinners = (yi == Ys ? Y.winners : Y.pref[yi].winners);


		if(YXreach[yi] == Xs && YYreach[yi] == Ys)
			res.winners += yiwinners;
		else if(YXreach[yi] == Xs)
		{
			newpref.push_back({YYreach[yi], yiwinners});

		}
		else if(YYreach[yi] == Ys)
		{
			newsuff.push_back({YXreach[yi], yiwinners});
		}
	}

	// cerr << "#5\n";

	for(auto pr : newpref)
	{
		for(auto& respr : res.pref)
		{
			// assert(pr.first < sz(Y.pref));

			if(pr.first == -1 && respr.i == X.r)
				respr.winners += pr.second;
			else if(pr.first != -1 && respr.i == Y.pref[pr.first].i)
				respr.winners += pr.second;
		}
	}
	// cerr << "hello\n";

	for(auto sf : newsuff)
	{
		// cerr << sf.first << ' ' << sf.second << '\n';
		for(auto& ressf : res.suff)
		{
			assert(sf.first < sz(X.suff));

			// cerr << "   " << ressf.i << ' ' << ressf.Asum << ' ' << ressf.winners << '\n';

			// cerr << "sff = " <<  sf.first << '\n';
			// cerr << X.suff[sf.first.i] << '\n';

			if(sf.first == -1 && ressf.i == Y.l)
			{
				// cerr << "bye\n";
				ressf.winners += sf.second;
				// cerr << "bye done\n";
			}
			else if(sf.first != -1 && ressf.i == X.suff[sf.first].i)
			{
				// cerr << "bye2\n";
				ressf.winners += sf.second;
			}
		}
	}


	// Y = info(1);

	// return res;

	// cerr << "combine end\n";
}

info combine(const info& A, const info& B)
{
	info res;
	combine(res, A, B);
	return res;
}


struct segtree
{
	info v;
	segtree* left = NULL;
	segtree* right = NULL;

	segtree()
	{
		;
	}

	segtree(int L, int R)
	{
		if(L == R)
			v = info(L);
		else
		{
			left = new segtree(L, (L+R)/2);
			right = new segtree((L+R)/2+1, R);
			combine(v, left->v, right->v);
		}
	}

	void recompute(int I)
	{
		// cerr << "recompute : " << v.l << ' ' << v.r << ' ' << I << '\n';
		if(v.l == v.r)
			v = info(v.l);
		else
		{
			if(I <= (v.l+v.r)/2)
				left->recompute(I);
			else
				right->recompute(I);

			// cerr << "###\n";

			combine(v, left->v, right->v);

			// cerr << "combine done\n";
		}
		// cerr << "done\n";
	}

	info range(int L, int R)
	{
		if(L <= v.l && v.r <= R)
			return v;
		else if(R <= (v.l+v.r)/2)
			return left->range(L, R);
		else if(L >= (v.l+v.r)/2+1)
			return right->range(L, R);
		else
			return combine(left->range(L, R), right->range(L, R));
	}
};

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	cin >> N;
	A = vll(1+N);
	for(int i = 1; i <= N; i++)
		cin >> A[i];

	// cerr << "done\n";

	segtree S(1, N);

	// cerr << "done2\n";


	cin >> Q;
	for(int j = 1; j <= Q; j++)
	{
		int T;
		cin >> T;

		if(T == 1)
		{
			int X, Y;
			cin >> X >> Y;
			A[X] = Y;
			S.recompute(X);
			// cerr << "hello\n";
		}
		else
		{
			int L, R;
			cin >> L >> R;
			cout << S.range(L, R).winners << '\n';
		}
	}
}		

Compilation message

fish2.cpp: In function 'void combine(info&, const info&, const info&)':
fish2.cpp:244:4: error: 'assert' was not declared in this scope
  244 |    assert(sf.first < sz(X.suff));
      |    ^~~~~~
fish2.cpp:4:1: note: 'assert' is defined in header '<cassert>'; did you forget to '#include <cassert>'?
    3 | #include <algorithm>
  +++ |+#include <cassert>
    4 | using namespace std;
fish2.cpp:162:6: warning: unused variable 'pi' [-Wunused-variable]
  162 |  int pi = sz(res.pref);
      |      ^~
fish2.cpp:175:6: warning: unused variable 'si' [-Wunused-variable]
  175 |  int si = sz(res.suff);
      |      ^~