蒟蒻的代码只能90pts,按照亮度的二级排序那里,当高度h相等的时候按亮度排,无论是大于号还是小于号,测试点#4和#9始终WA一个,就是不能同时正确
所以加了一个随机数来随机选择一种大于或小于排序,可以卡过
蒟蒻的代码:
#include <cstdio>
#include <algorithm>
#include <random>
#define int long long
using namespace std;
const int N = 4e6;
// 快读快写
inline int read(){
int _x = 0, _w = 1;
char ch = 0;
while(ch < '0' || ch > '9') {
if(ch == '-') _w = -1;
#ifdef __linux__
ch = (char)getchar_unlocked();
#else
ch = (char) _getchar_nolock();
#endif
}
while(ch >= '0' && ch <= '9') {
_x = (_x << 3) + (_x << 1) + (ch - '0');
#ifdef __linux__
ch = (char)getchar_unlocked();
#else
ch = (char) _getchar_nolock();
#endif
}
return _x * _w;
}
inline void write(int _x){
if(_x < 0) {
#ifdef __linux__
putchar_unlocked('-');
#else
_putchar_nolock('-');
#endif
_x = -_x;
}
static int _sta[130];
int _top = 0;
do {
_sta[_top++] = _x % 10, _x /= 10;
} while(_x);
while(_top)
#ifdef __linux__
putchar_unlocked(_sta[--_top] + 48);
putchar_unlocked('\n');
#else
_putchar_nolock(_sta[--_top] + 48);
_putchar_nolock('\n');
#endif
}
int T, n, W, H, x1, Y1, x2, y2;
int X[N << 1];
// 玄学操作
default_random_engine e;
struct ScanLine {
int l, r, h;
int mark, light;
// 随机选一种排序
bool operator<(const ScanLine &t) const{
return h == t.h ? (e() % 2 == 1 ? light < t.light : light > t.light) : h < t.h;
}
} line[N];
struct Node {
int l, r;
int sum, Max;
int newValue;
bool change;
} tr[4 * N];
inline void pushUp(int u){
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
tr[u].Max = max(tr[u << 1].Max, tr[u << 1 | 1].Max);
}
inline void pushDown(int u){
auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
if(root.change) {
left.newValue += root.newValue, left.sum +=
(left.r - left.l + 1) * root.newValue, left.change = true, left.Max += root.newValue;
right.newValue += root.newValue, right.sum +=
(right.r - right.l + 1) * root.newValue, right.change = true, right.Max += root.newValue;
root.change = false;
root.newValue = 0;
}
}
void build(int u, int l, int r){
tr[u] = {l, r, 0, 0, 0, false};
if(l == r)
return;
int mid = (l + r) >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushUp(u);
}
int query(int u, int l, int r){
if(l > r)
return 0;
if(l <= tr[u].l && tr[u].r <= r)
return tr[u].Max;
pushDown(u);
int mid = (tr[u].l + tr[u].r) >> 1;
int Max = 0;
if(l <= mid)
Max = max(Max, query(u << 1, l, r));
if(r > mid)
Max = max(Max, query(u << 1 | 1, l, r));
pushUp(u);
return Max;
}
void modify(int u, int l, int r, int d){
if(l <= tr[u].l && tr[u].r <= r) {
tr[u].sum += (tr[u].r - tr[u].l + 1) * d;
tr[u].newValue += d;
tr[u].Max += d;
tr[u].change = true;
} else {
pushDown(u);
int mid = (tr[u].l + tr[u].r) >> 1;
if(l <= mid)
modify(u << 1, l, r, d);
if(r > mid)
modify(u << 1 | 1, l, r, d);
pushUp(u);
}
}
signed main(){
T = read();
while(T--) {
n = read(), W = read(), H = read();
for(int i = 1; i <= n; i++) {
int x = read(), y = read(), light = read();
x1 = x, Y1 = y, x2 = x + W, y2 = y + H;
X[2 * i] = x1;
X[2 * i - 1] = x2;
line[2 * i] = {x1, x2, Y1, 1, light};
line[2 * i - 1] = {x1, x2, y2, -1, light};
}
n <<= 1;
sort(X + 1, X + 1 + n);
stable_sort(line + 1, line + n + 1);
int tot = unique(X + 1, X + 1 + n) - X - 1;
build(1, 1, tot - 1);
int ans = 0;
for(int i = 1; i < n; i++) {
int newL = lower_bound(X + 1, X + tot + 1, line[i].l) - X;
int newR = lower_bound(X + 1, X + tot + 1, line[i].r) - X;
modify(1, newL, newR - 1, line[i].mark * line[i].light);
ans = max(ans, query(1, 1, tot - 1));
}
write(ans);
}
return 0;
}