QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#948513#4417. Shallow MoonjijidawangAC ✓1483ms52024kbC++144.2kb2025-03-23 08:37:492025-03-23 08:37:50

Judging History

This is the latest submission verdict.

  • [2025-03-23 08:37:50]
  • Judged
  • Verdict: AC
  • Time: 1483ms
  • Memory: 52024kb
  • [2025-03-23 08:37:49]
  • Submitted

answer

#include <bits/stdc++.h>
namespace // my guiding star
{
#define filein(x) freopen(x".in", "r", stdin);
#define fileout(x) freopen(x, "w", stdout);
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout);
#define files(x) freopen(x".in", "r", stdin), freopen(x".ans", "w", stdout);
using namespace std;
#define cT const T&
template<typename T>
inline T chkmin(T& x, cT y){if (x > y) x = y; return x;}
template<typename T>
inline T chkmax(T& x, cT y){if (x < y) x = y; return x;}
template <typename T>
inline bool inrange(cT x, cT l, cT r){return (l <= x) && (x <= r);}
template <typename T>
inline bool inrange(cT l, cT r, cT L, cT R){return (L <= l) && (r <= R);}
#undef cT
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef unsigned u32;
template <typename T>
using pr = pair<T, T>;
typedef pr<int> pii;
typedef pr<ll> pll;
typedef pr<db> pdd;
typedef vector<int> vi;
inline void YN(bool x){puts(x ? "Yes" : "No");}
}
const int N = 1e6 + 233;
int n, m, w, h;
map<int, vector<tuple<int, int, int>>> M;
struct dsu
{
	int fa[N]; ull siz[N];
	inline void init(int n){for (int i=1; i<=n; i++){fa[i] = i; siz[i] = 0;}}
	int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}
	inline void merge(int u, int v)
	{
		u = find(u); v = find(v);
		if (u == v) return ;
		fa[u] = v; siz[v] += siz[u];
	}
}D;
namespace IO {
  char buf[1 << 21], *p1 = buf, *p2 = buf;
  #define gc (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
  inline int read() {
    int x = 0;
    char s = gc;
    while(!isdigit(s)) s = gc;
    while(isdigit(s)) x = x * 10 + s - '0', s = gc;
    return x;
  }
}
using namespace IO;
int main()
{
	int T = read(); D.init(N - 1);
	while (T--)
	{
		n = read(); m = read(); w = read(); h = read();
		for (int i=1, x, y; i<=n; i++)
		{
			x = read(); y = read();
			if ((x + w - 2) / w) M[(x + w - 2) / w].emplace_back(y, w - 1 - (x - 2 + w) % w, 2);
			M[(x + w - 2) / w + 1].emplace_back(y, (x - 2 + w) % w, 1);
		}
		int lst = 0, cc = 0;
		vector<tuple<int, int, int>> id;
		M[(m + w - 1) / w].emplace_back();
		for (auto [x, v] : M)
		{
			if (x - lst > 1)
			{
				int R = (x - 1) * w, L = lst * w + 1;
				++cc; D.siz[cc] = 1ull * (R - L + 1) * m;
				for (auto [u, l, r] : id) D.merge(cc, u);
				id = {{cc, 1, m}};
			}
			int width = min(m, x * w) - (x - 1) * w;
			vector<tuple<int, int, int>> vr;
			for (auto [p, c, o] : v)
				if (p){vr.emplace_back(p, c, o); vr.emplace_back(p + h, c, -o);}
			vr.emplace_back(1, 0, 0); vr.emplace_back(m + 1, 0, 0);
			stable_sort(vr.begin(), vr.end());
			vector<pair<int, vector<pair<int, ull>>>> op;
			int L = -1; vector<pair<int, ull>> qwq;
			for (auto [p, c, o] : vr)
			{
				if (p != L){if (L != -1) op.emplace_back(L, qwq); qwq.clear();}
				qwq.emplace_back(c, o); L = p;
			}
			if (!qwq.empty()) op.emplace_back(L, qwq);
			multiset<int> sU, sD;
			vector<tuple<int, int, int>> nid;
			auto ptr = id.begin();
			int lstL = -1, lstR = -1;
			for (auto p = op.begin(); p != prev(op.end()); ++p)
			{
				for (auto [x, o] : p -> second)
				{
					if (o == 2) sD.insert(x);
					if (o == 1) sU.insert(x);
					if (o == -1) sU.erase(sU.find(x));
					if (o == -2) sD.erase(sD.find(x));
				}
				int l = p -> first, r = next(p) -> first - 1;
				int uL = sU.empty() ? -1 : *--sU.end(), uR = sD.empty() ? 0 : *--sD.end();
				++uL; uR = width - uR - 1;
				if (uL > uR){lstL = lstR = -1; continue;}
				++cc;
				if (sD.empty()) nid.emplace_back(cc, l, r);
				D.siz[cc] = 1ull * (r - l + 1) * (uR - uL + 1);
				if ((p != op.begin()) && ~lstL && (inrange(lstL, uL, uR) || inrange(lstR, uL, uR) || inrange(uL, lstL, lstR) || inrange(uR, lstL, lstR))) D.merge(cc - 1, cc);
				while ((ptr != id.end()) && (get<2>(*ptr) < l)) ++ptr;
				auto tp = ptr;
				while ((tp != id.end()) && (get<1>(*tp) <= r)){D.merge(cc, get<0>(*tp)); ++tp;}
				lstL = uL; lstR = uR;
			}
			id = nid; lst = x;
		}
		ull ans = 0; 
		for (int i=1; i<=cc; i++)
			if (D.find(i) == i) ans += D.siz[i] * D.siz[i];
		printf("%llu\n", ans);
		D.init(cc); M.clear();
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1483ms
memory: 52024kb

input:

501
1000 1000000000 8 6
196705452 282810113
937875223 275529064
629271205 864549686
750495261 246485461
543433237 255456903
488123456 624378383
54011768 202210239
202279514 480198740
310520275 178661688
643456981 428672131
21485303 109706962
473119724 616638896
589883353 354364583
907646968 63640664...

output:

9775754433921302528
12719218429090003200
3102866340934553600
1731322551472548096
9775754433921302528
12518842016069313536
1900607941410415616
17573173619913134080
621479607805049408
16047889703994672128
9451871597547151424
15246384117911913472
3393948179234228288
15136715046354208832
122709744547405...

result:

ok 501 lines