답안 #706028

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
706028 2023-03-05T18:50:53 Z 600Mihnea 가로등 (APIO19_street_lamps) C++17
20 / 100
5000 ms 256348 KB
#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <cassert>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <numeric>

using namespace std;

typedef long long ll;

struct T
{
	int i;
	int t1;
	int t2;
};

struct Q
{
	int l;
	int r;
	int iq;
};

struct Segment
{
	int l;
	int r;
	int x;
};

bool operator < (Segment a, Segment b)
{
	return make_pair(a.l, a.r) < make_pair(b.l, b.r);
}

struct Update
{
	int x;
	int y;
	ll val;
};

signed main()
{
#ifdef ONPC	
	FILE* stream;
	freopen_s(&stream, "input.txt", "r", stdin);
#else
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#endif

	int n, q;
	string init_config;
	cin >> n >> q >> init_config;
	assert((int)init_config.size() == n);
	for (auto& ch : init_config)
	{
		assert(ch == '0' || ch == '1');
	}
	vector<T> v;
	vector<int> since(n, 0);
	string cur_config = init_config;
	vector<vector<int>> ops(q);
	vector<int> printsol(q, -1);
	for (int iq = 0; iq < q; iq++)
	{
		string s;
		cin >> s;
		assert(s == "query" || s == "toggle");
		if (s == "query")
		{
			int l, r;
			cin >> l >> r;
			l--;
			r--;
			r--;
			assert(0 <= l && l <= r && r < n);
			ops[iq] = { l, r };
		}
		else
		{
			assert(s == "toggle");
			int i;
			cin >> i;
			i--;
			assert(0 <= i && i < n);
			cur_config[i] = '0' ^ '1' ^ cur_config[i];
			if (cur_config[i] == '1')
			{
				v.push_back({ i, since[i], iq - 1 + 1 });
			}
			else
			{
				since[i] = iq + 1;
			}
			ops[iq] = { i };
		}
	}
	for (int i = 0; i < n; i++)
	{
		if (cur_config[i] == '0')
		{
			v.push_back({ i, since[i], q });
		}
	}
	vector<Q> qs;

	for (int iq = 0; iq < q; iq++)
	{
		if ((int)ops[iq].size() == 2)
		{
			int l = ops[iq][0], r = ops[iq][1];
			qs.push_back({ l, r, iq });

		}
	}
	sort(v.begin(), v.end(), [&](T a, T b) {return a.i > b.i; });
	sort(qs.begin(), qs.end(), [&](Q a, Q b) {return a.l > b.l; });
	vector<vector<int>> interestingPoints(q + 7);
	vector<vector<ll>> aib(q + 7);
	{
		vector<int> what(q + 1, (int)1e9), coef(q + 1, 0);
		set<Segment> s;
		what[0] = -1;
		coef[0] = q + 1;
		s.insert({ 0, q, -1 });
		int pz = 0;
		vector<Update> updates;
		updates.push_back({ 0 + 1, what[0] + 1, coef[0] });
		for (auto& itqs : qs)
		{
			int l = itqs.l;
			vector<int> nr(q + 1, 0);
			int sol = 0;
			while (pz < (int)v.size() && l <= v[pz].i)
			{
				int st = v[pz].t1, dr = v[pz].t2;
				while (1)
				{
					auto it = s.lower_bound({ dr + 1, -1, 0 });
					if (it == s.begin())
					{
						break;
					}
					it--;
					assert(it->l <= dr);
					if (it->r < st)
					{
						break;
					}
					assert(it->l <= dr);
					assert(st <= it->r);
					vector<Segment> bg;
					if (dr + 1 <= it->r)
					{
						bg.push_back({ dr + 1, it->r, it->x });
					}
					if (it->l <= st - 1)
					{
						bg.push_back({ it->l, st - 1, it->x });
					}
					updates.push_back({ it->l + 1, what[it->l] + 1, -coef[it->l] });
					coef[it->l] = 0;
					s.erase(it);
					for (auto& gu : bg)
					{

						updates.push_back({ gu.l + 1, what[gu.l] + 1, -coef[gu.l] });
						what[gu.l] = gu.x;
						coef[gu.l] = gu.r - gu.l + 1;
						updates.push_back({ gu.l + 1, what[gu.l] + 1, +coef[gu.l] });
						s.insert(gu);
					}
				}
				updates.push_back({ st + 1, what[st] + 1, -coef[st] });
				what[st] = pz;
				coef[st] = dr - st + 1;
				updates.push_back({ st + 1, what[st] + 1, coef[st] });
				s.insert({ st, dr, pz });
				pz++;
			}
		}
		for (auto& u : updates)
		{
			for (int i = u.x; i < (int)interestingPoints.size(); i += i & (-i))
			{
				interestingPoints[i].push_back(u.y);
			}
		}
		for (int x = 1; x < (int)interestingPoints.size(); x++)
		{
			sort(interestingPoints[x].begin(), interestingPoints[x].end());
			interestingPoints[x].resize(unique(interestingPoints[x].begin(), interestingPoints[x].end()) - interestingPoints[x].begin());
			aib[x].resize((int)interestingPoints[x].size() + 1, 0);
		}
	}
	{
		auto upd = [&](int x, int y, ll val)
		{
			if (val == 0)
			{
				return;
			}
			for (int i = x; i < (int)interestingPoints.size(); i += i & (-i))
			{
				int go = lower_bound(interestingPoints[i].begin(), interestingPoints[i].end(), y) - interestingPoints[i].begin();
				assert(0 <= go && go < (int)interestingPoints[i].size());
				assert(interestingPoints[i][go] == y);
				go++;
				for (int j = go; j < (int)aib[i].size(); j += j & (-j))
				{
					aib[i][j] += val;
				}
			}
		};
		auto get = [&](int x, int y)
		{
			ll sol = 0;
			for (int i = x; i >= 1; i -= i & (-i))
			{
				int cnt = 0, low = 0, high = (int)interestingPoints[i].size() - 1;
				while (low <= high)
				{
					int mid = (low + high) / 2;
					if (interestingPoints[i][mid] <= y)
					{
						cnt = mid + 1;
						low = mid + 1;
					}
					else
					{
						high = mid - 1;
					}
				}
				for (int j = cnt; j >= 1; j -= j & (-j))
				{
					sol += aib[i][j];
				}
			}
			return sol;
		};
		vector<int> what(q + 1, (int)1e9), coef(q + 1, 0);
		set<Segment> s;
		what[0] = -1;
		coef[0] = q + 1;
		s.insert({ 0, q, -1 });
		int pz = 0;
		upd(0 + 1, what[0] + 1, coef[0]);
		for (auto& itqs : qs)
		{
			int l = itqs.l;
			vector<int> nr(q + 1, 0);
			int sol = 0;
			while (pz < (int)v.size() && l <= v[pz].i)
			{
				int st = v[pz].t1, dr = v[pz].t2;
				while (1)
				{
					auto it = s.lower_bound({ dr + 1, -1, 0 });
					if (it == s.begin())
					{
						break;
					}
					it--;
					assert(it->l <= dr);
					if (it->r < st)
					{
						break;
					}
					assert(it->l <= dr);
					assert(st <= it->r);
					vector<Segment> bg;
					if (dr + 1 <= it->r)
					{
						bg.push_back({ dr + 1, it->r, it->x });
					}
					if (it->l <= st - 1)
					{
						bg.push_back({ it->l, st - 1, it->x });
					}
					upd(it->l + 1, what[it->l] + 1, -coef[it->l]);
					coef[it->l] = 0;
					s.erase(it);
					for (auto& gu : bg)
					{
						upd(gu.l + 1, what[gu.l] + 1, -coef[gu.l]);
						what[gu.l] = gu.x;
						coef[gu.l] = gu.r - gu.l + 1;
						upd(gu.l + 1, what[gu.l] + 1, +coef[gu.l]);
						s.insert(gu);
					}
				}
				upd(st + 1, what[st] + 1, -coef[st]);
				what[st] = pz;
				coef[st] = dr - st + 1;
				upd(st + 1, what[st] + 1, coef[st]);
				s.insert({ st, dr, pz });
				pz++;
			}
			int r = itqs.r, iq = itqs.iq;;
			///it2.i <= r
			/// 0 0 0 0 0 1 1 1 1 1 1 
			int Start = pz, low = 0, high = pz - 1;
			while (low <= high)
			{
				int jo = (low + high) / 2;
				if (v[jo].i <= r)
				{
					Start = jo;
					high = jo - 1;
				}
				else
				{
					low = jo + 1;
				}
			}
			auto it = s.lower_bound({ iq + 1, -1, 0 });
			assert(it != s.begin());
			it--;
			if (it->x <= Start - 1)
			{
				sol += iq - it->l + 1;
			}

			if (it != s.begin())
			{
				it--;
				int ant = it->l;
				sol += get(ant + 1, Start);
			}
			printsol[iq] = sol;
		}

	}
	for (int iq = 0; iq < q; iq++)
	{
		if ((int)ops[iq].size() == 2)
		{
			cout << printsol[iq] << "\n";
		}
	}
	return 0;
}

Compilation message

street_lamps.cpp: In function 'int main()':
street_lamps.cpp:154:8: warning: unused variable 'sol' [-Wunused-variable]
  154 |    int sol = 0;
      |        ^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 1 ms 340 KB Output is correct
7 Correct 1 ms 212 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5059 ms 104220 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 724 KB Output is correct
2 Correct 3 ms 724 KB Output is correct
3 Correct 2 ms 596 KB Output is correct
4 Correct 1 ms 468 KB Output is correct
5 Correct 3373 ms 256348 KB Output is correct
6 Execution timed out 5047 ms 213272 KB Time limit exceeded
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 596 KB Output is correct
2 Correct 3 ms 724 KB Output is correct
3 Correct 4 ms 724 KB Output is correct
4 Correct 5 ms 852 KB Output is correct
5 Execution timed out 5088 ms 54824 KB Time limit exceeded
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 1 ms 340 KB Output is correct
7 Correct 1 ms 212 KB Output is correct
8 Execution timed out 5059 ms 104220 KB Time limit exceeded
9 Halted 0 ms 0 KB -