QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#267731 | #6304. Rectangle | zhaohaikun | WA | 18ms | 46452kb | C++14 | 8.4kb | 2023-11-27 17:29:26 | 2023-11-27 17:29:26 |
Judging History
answer
// MagicDark
#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define ls num << 1
#define rs ls | 1
#define li ls, l, mid
#define ri rs, mid + 1, r
#define x1 cryforthezi1
#define x2 cryforthezi2
#define y1 cryforthezi3
#define y2 cryforthezi4
#define debug cerr << "[" << __LINE__ << "] "
#define SZ(x) (int) x.size() - 1
#define all(x) x.begin(), x.end()
#define ms(x, y) memset(x, y, sizeof x)
#define F(i, x, y) for (int i = (x); i <= (y); i++)
#define DF(i, x, y) for (int i = (x); i >= (y); i--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
template <typename T> inline void chkmax(T &x, T y) {x = max(x, y);}
template <typename T> inline void chkmin(T &x, T y) {x = min(x, y);}
template <typename T> inline void read(T &x) {
x = 0; int f = 1; char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
x *= f;
}
const int N = 2e5 + 10, MOD = 998244353, T = 1e9, inv6 = 166374059;
int n, x1[N], y1[N], x2[N], y2[N], yy[N], ans, lp[N], rp[N];
int cx, cy, tx[N], ty[N];
int len[N << 2], mx[N << 2], tag[N << 2], seg[N << 2], lmax[N], rmin[N];
inline void add(int &x, ll y) {x = (x + y) % MOD;}
void build(int num, int l, int r) {
seg[num] = mx[num] = tag[num] = 0, len[num] = ty[r + 1] - ty[l];
if (l == r) return;
build(li), build(ri);
}
vector <tuple <int, int, int, int>> g1;
vector <tuple <int, int>> g2;
vector <tuple <int, int, int>> g3;
void down(int num, int x) {
g1.emplace_back(num, mx[num], tag[num], seg[num]);
mx[num] = tag[num] = x;
seg[num] = (ll) len[num] * x % MOD;
}
void pushdown(int num) {
if (tag[num]) {
g2.emplace_back(num, tag[num]);
down(ls, tag[num]), down(rs, tag[num]);
tag[num] = 0;
}
}
void pushup(int num) {
g3.emplace_back(num, mx[num], seg[num]);
mx[num] = mx[rs];
seg[num] = (seg[ls] + seg[rs]) % MOD;
}
void change(int num, int l, int r, int L, int R, int x) {
if (L <= l && r <= R) return down(num, x);
pushdown(num);
if (mid >= L) change(li, L, R, x);
if (mid < R) change(ri, L, R, x);
pushup(num);
}
int query(int num, int l, int r, int L, int R) {
if (L <= l && r <= R) return seg[num];
pushdown(num);
if (mid >= R) return query(li, L, R);
if (mid < L) return query(ri, L, R);
return (query(li, L, R) + query(ri, L, R)) % MOD;
}
int findpos(int num, int l, int r, int x) {
if (l == r) return l;
pushdown(num);
if (mx[ls] > x) return findpos(li, x);
return findpos(ri, x);
}
vector <int> gg[N << 2];
void modify(int num, int l, int r, int L, int R, int x) {
if (L <= l && r <= R) return gg[num].push_back(x);
if (mid >= L) modify(li, L, R, x);
if (mid < R) modify(ri, L, R, x);
}
void analysis(int num, int l, int r) {
unsigned t1 = g1.size(), t2 = g2.size(), t3 = g3.size();
for (int id: gg[num]) {
int g = mx[1] <= y1[id] ? cy : findpos(1, 1, cy, y1[id]) - 1;
// debug << mx[1] << endl;
// debug << "~ " << id << " " << yy[id] << " " << g << " " << y1[id] << endl;
if (yy[id] <= g) change(1, 1, cy, yy[id], g, y1[id]);
}
if (l == r) {
if (lmax[l] > rmin[l]) {
int L = lower_bound(ty + 1, ty + cy + 1, lmax[l]) - ty;
if (L <= cy) {
int R = mx[1] <= rmin[l] ? cy : findpos(1, 1, cy, rmin[l]) - 1;
if (L <= R) {
// debug << L << " " << R << endl;
add(ans, ((ll) (ty[R + 1] - ty[L]) * (rmin[l] + 1) % MOD - query(1, 1, cy, L, R) + MOD) * (tx[l + 1] - tx[l]));
// debug << l << " " << ((ll) (ty[R + 1] - ty[L]) * (rmin[l] + 1) % MOD - query(1, 1, cy, L, R) + MOD) * (tx[l + 1] - tx[l]) % MOD << endl;
// debug << query(1, 1, cy, L, R) << endl;
// debug << l << " " << L << " " << R << " " << ans << " " << lmax[l] << " " << rmin[l] << endl;
// debug << query(1, 1, cy, 4, 4) << endl;
}
}
}
} else analysis(li), analysis(ri);
while (g1.size() > t1) {
int id = get <0> (g1.back());
mx[id] = get <1> (g1.back());
tag[id] = get <2> (g1.back());
seg[id] = get <3> (g1.back());
g1.pop_back();
}
while (g2.size() > t2) {
int id = get <0> (g2.back());
tag[id] = get <1> (g2.back());
g2.pop_back();
}
while (g3.size() > t3) {
int id = get <0> (g3.back());
mx[id] = get <1> (g3.back());
seg[id] = get <2> (g3.back());
g3.pop_back();
}
}
struct P1 {// 大根堆
priority_queue <int> q1, q2;
void insert(int x) {
q1.push(x);
}
void erase(int x) {
q2.push(x);
}
unsigned size() {
return q1.size() - q2.size();
}
bool empty() {
return q1.size() == q2.size();
}
int top() {
while (q2.size() && q2.top() == q1.top()) q1.pop(), q2.pop();
return q1.top();
}
void pop() {
while (q2.size() && q2.top() == q1.top()) q1.pop(), q2.pop();
q1.pop();
}
};
struct P2 {// 小根堆
priority_queue <int, vector <int>, greater <int>> q1, q2;
void insert(int x) {
q1.push(x);
}
void erase(int x) {
q2.push(x);
}
unsigned size() {
return q1.size() - q2.size();
}
bool empty() {
return q1.size() == q2.size();
}
int top() {
while (q2.size() && q2.top() == q1.top()) q1.pop(), q2.pop();
return q1.top();
}
void pop() {
while (q2.size() && q2.top() == q1.top()) q1.pop(), q2.pop();
q1.pop();
}
};
vector <int> ins[N], del[N];//, preins[N], sufins[N];
int t1[N];
bool t2[N];
void solve() {
F(i, 1, 2 * n + 5) {
ins[i].clear();
del[i].clear();
}
F(i, 1, 8 * n + 10) {
gg[i].clear();
}
cx = 0, cy = 0;
tx[++cx] = 1;
ty[++cy] = 1;
F(i, 1, n) {
tx[++cx] = x1[i];
if (x2[i] != T) tx[++cx] = x2[i] + 1;
ty[++cy] = y1[i];
if (y2[i] != T) ty[++cy] = y2[i] + 1;
}
sort(tx + 1, tx + cx + 1);
F(i, 1, cx) lp[i] = 0, rp[i] = T + 1;
sort(ty + 1, ty + cy + 1);
tx[(cx = unique(tx + 1, tx + cx + 1) - tx)--] = T + 1;
ty[(cy = unique(ty + 1, ty + cy + 1) - ty)--] = T + 1;
build(1, 1, cy);
F(i, 1, n) {
int x1 = lower_bound(tx + 1, tx + cx + 1, ::x1[i]) - tx;
int x2 = lower_bound(tx + 1, tx + cx + 1, ::x2[i] + 1) - tx;
chkmax(lp[x2], ::x1[i]);
chkmin(rp[x1 - 1], ::x2[i]);
yy[i] = lower_bound(ty + 1, ty + cy + 1, y2[i] + 1) - ty;
if (x1 > 1) modify(1, 1, cx, 1, x1 - 1, i), ins[1].push_back(i), del[x1].push_back(i);
if (x2 <= cx) modify(1, 1, cx, x2, cx, i), ins[x2].push_back(i);
}
P1 l;
P2 r;
int L = 1, R = T;
F(i, 1, cx) {
for (int j: ins[i]) {
l.insert(y1[j]);
r.insert(y2[j]);
}
for (int j: del[i]) {
l.erase(y1[j]);
r.erase(y2[j]);
}
if (l.empty()) lmax[i] = 0, add(ans, (ll) T * (T - 1) / 2 % MOD * (tx[i + 1] - tx[i]));//, debug << i << " " << (ll) T * (T - 1) / 2 % MOD * (tx[i + 1] - tx[i]) % MOD;
else {
lmax[i] = l.top(), rmin[i] = r.top();
if (lmax[i] <= rmin[i]) {
add(ans, ((ll) T * (T - 1) / 2 - (ll) (T - (rmin[i] - lmax[i] + 1)) * (T - (rmin[i] - lmax[i] + 1) - 1) / 2) % MOD * (tx[i + 1] - tx[i]));//, debug << i << " " << ((ll) T * (T - 1) / 2 - (ll) (T - (rmin[i] - lmax[i] + 1)) * (T - (rmin[i] - lmax[i] + 1) - 1) / 2) % MOD * (tx[i + 1] - tx[i]) % MOD << " " << lmax[i] << " " << rmin[i] << " " << tx[i + 1] - tx[i] << endl;
swap(lmax[i], rmin[i]);
lmax[i]++;
rmin[i]--;
}
}
if (lp[i]) {
chkmax(L, lp[i]);
chkmin(R, tx[i] - 1);
}
t1[i] = max(0, min(tx[i] - 1, R) - L + 1);
t2[i] = R >= tx[i];
// debug << i << " " << L << " " << R << endl;
}
L = 1, R = T;
DF(i, cx, 1) {
if (rp[i] <= T) {
chkmax(L, tx[i + 1]);
chkmin(R, rp[i]);
}
int k1 = max(0, R - max(tx[i + 1], L) + 1);
bool k2 = L <= tx[i];
add(ans, (ll) (tx[i + 1] - tx[i]) * t1[i] % MOD * k1);
// debug << i << " " << t2[i] << " " << k2 << endl;
if (t2[i]) add(ans, (ll) (tx[i + 1] - tx[i]) * (tx[i + 1] - tx[i] - 1) / 2 % MOD * k1);
if (k2) add(ans, (ll) (tx[i + 1] - tx[i]) * (tx[i + 1] - tx[i] - 1) / 2 % MOD * t1[i]);
if (t2[i] && k2) add(ans, (ll) (tx[i + 1] - tx[i]) * (tx[i + 1] - tx[i] - 1) % MOD * (tx[i + 1] - tx[i] - 2) % MOD * inv6);
// debug << i << " " << ans << endl;
}
// debug << ans << endl;
// exit(0);
analysis(1, 1, cx);
// debug << ans << endl;
// debug << cx << " " << ans << endl;
// exit(0);
}
void zhk() {
ans = 0;
read(n);
F(i, 1, n) read(x1[i]), read(y1[i]), read(x2[i]), read(y2[i]);
solve();
// debug << ans << endl;
F(i, 1, n) swap(x1[i], y1[i]), swap(x2[i], y2[i]);
solve();
cout << ans << '\n';
}
signed main() {
// debug << (T - 1) % MOD << endl;
int _ = 1;
cin >> _;
while (_--) zhk();
return 0;
}
/* why?
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 46392kb
input:
3 1 1 1 1000000000 1000000000 3 1 1 2 2 3 3 4 4 5 5 6 6 5 581574116 47617804 999010750 826131769 223840663 366320907 613364068 926991396 267630832 51913575 488301124 223957497 217461197 492085159 999485867 913732845 28144453 603781668 912516656 993160442
output:
230616300 64 977066618
result:
ok 3 number(s): "230616300 64 977066618"
Test #2:
score: -100
Wrong Answer
time: 18ms
memory: 46452kb
input:
1000 10 5 7 6 10 4 3 6 9 1 6 3 7 1 1 7 10 1 2 7 7 5 2 8 3 2 1 5 7 1 1 10 6 1 7 2 8 4 7 5 9 10 6 6 8 10 4 4 9 9 2 4 6 5 5 3 10 10 1 3 4 4 2 2 3 6 7 5 8 6 2 7 8 8 5 7 10 10 2 4 7 8 10 3 6 6 10 1 2 7 4 7 5 10 9 4 5 8 9 2 7 5 9 2 2 9 7 3 3 8 4 1 1 8 6 5 4 10 6 3 9 7 10 10 3 1 8 9 1 3 8 10 4 1 7 4 2 4 5 ...
output:
28090346 21067813 91293527 63203269 14045217 24579047 49158123 56180656 10533939 83 28090370 101827336 512901422 38624242 10533926 42135595 7022611 7022661 7022622 31601639 21067817 35112979 7022628 7022679 17556483 42135554 59692019 28090452 14045202 73737096 42135505 31601703 49158090 28090434 108...
result:
wrong answer 2nd numbers differ - expected: '21067815', found: '21067813'