# 【BZOJ2639】矩形计算（四维偏序）

BZOJ 同时被 2 个专栏收录
218 篇文章 0 订阅
11 篇文章 0 订阅

## Code

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
#define Rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define X first
#define Y second
#define PB(a) push_back(a)
#define MP(a, b) make_pair(a, b)
#define SZ(a) ((int)(a).size())
#define ALL(a) a.begin(), a.end()
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaia
#define sqr(x) ((x) * (x))

template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }

inline int read() {
static int _, __; static char c_;
for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1;
for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
return _ * __;
}
//EOT

const int maxn = 233, maxm = 233 * 233, S = 35, sumc = maxm / S + 5, maxq = 201314;

int n, m, q, ls[maxm], lss, ans[maxq], ty[maxm], cnt[maxm], a[maxn][maxn];

struct Query {
int x1, y1, x2, y2;
}qry[maxq];

namespace FuckYouAll {
int lss, ls[maxm], sum[maxn][maxn];
inline void Main() {
For(k, 1, lss) {
For(i, 1, n) For(j, 1, m)
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (a[i][j] == ls[k]);
For(p, 1, q) {
ans[p] += sqr(sum[qry[p].x2][qry[p].y2] + sum[qry[p].x1 - 1][qry[p].y1 - 1]
- sum[qry[p].x1 - 1][qry[p].y2] - sum[qry[p].x2][qry[p].y1 - 1]);
}
}
}
}

namespace LoveYouForever {
int lss, ls[maxn * maxn];

struct Point { int a, b, c, d, id; }p[S * maxm + maxq];
int ps;
inline bool cmp(Point A, Point B) {
if (A.a != B.a) return A.a < B.a;
if (A.b != B.b) return A.b < B.b;
if (A.c != B.c) return A.c < B.c;
if (A.d != B.d) return A.d < B.d;
return A.id < B.id;
}

struct BIT {
int c[maxn][maxn][maxn];
#define lb(x) ((x) & -(x))
inline void update(int x, int y, int z) {
for (int i = x; i <= m; i += lb(i))
for (int j = y; j <= n; j += lb(j))
for (int k = z; k <= m; k += lb(k))
++ c[i][j][k];
}
inline int query(int x, int y, int z) {
int ans = 0;
for (int i = x; i; i -= lb(i))
for (int j = y; j; j -= lb(j))
for (int k = z; k; k -= lb(k))
ans += c[i][j][k];
return ans;
}
}bit;

vector<PII> vct[maxm];

inline void Main() {
For(i, 1, n) For(j, 1, m) if (ty[a[i][j]] == 2)
vct[lower_bound(ls + 1, ls + 1 + lss, a[i][j]) - ls].push_back(MP(i, j));
For(i, 1, lss) {
Rep(j, SZ(vct[i])) Rep(k, SZ(vct[i])) {
int x1 = vct[i][j].X, y1 = vct[i][j].Y, x2 = vct[i][k].X, y2 = vct[i][k].Y;
if (x1 > x2) swap(x1, x2);
if (y1 > y2) swap(y1, y2);
p[++ ps] = (Point){n - x1 + 1, m - y1 + 1, x2, y2, 0};
}
}
For(i, 1, q)
p[++ ps] = (Point){n - qry[i].x1 + 1, m - qry[i].y1 + 1, qry[i].x2, qry[i].y2, i};
sort(p + 1, p + 1 + ps, cmp);
//For(i, 1, ps) cout << p[i].a << ' ' << p[i].b << ' ' << p[i].c << ' ' << p[i].d << ' ' << p[i].id<< endl;
For(i, 1, ps)
if (!p[i].id) bit.update(p[i].b, p[i].c, p[i].d);
else ans[p[i].id] += bit.query(p[i].b, p[i].c, p[i].d);
}
}

int main()
{
#ifdef hany01
freopen("vegetable.in", "r", stdin);
freopen("vegetable.out", "w", stdout);
#endif

For(i, 1, n) For(j, 1, m) ls[(i - 1) * m + j] = a[i][j] = read();
sort(ls + 1, ls + 1 + n * m), lss = unique(ls + 1, ls + 1 + n * m) - ls - 1;
For(i, 1, n) For(j, 1, m) ++ cnt[a[i][j] = lower_bound(ls + 1, ls + 1 + lss, a[i][j]) - ls];
For(i, 1, lss)
if (cnt[i] > S) FuckYouAll::ls[++ FuckYouAll:: lss] = i, ty[i] = 1;
else LoveYouForever:: ls[++ LoveYouForever:: lss] = i, ty[i] = 2;
For(i, 1, q) {
if (qry[i].x1 > qry[i].x2) swap(qry[i].x1, qry[i].x2);
if (qry[i].y1 > qry[i].y2) swap(qry[i].y1, qry[i].y2);
}

FuckYouAll:: Main();
LoveYouForever:: Main();
For(i, 1, q) printf("%d\n", ans[i]);

return 0;
}

• 1
点赞
• 0
评论
• 0
收藏
• 打赏
• 扫一扫，分享海报

03-20 146
12-19 119

09-19 438
11-01 614
11-14 112
03-08 323
10-09 791
05-06 37
02-19 460
05-05 69
11-02 156
10-10 193
06-24 812
05-10 86
©️2022 CSDN 皮肤主题：撸撸猫 设计师：马嘣嘣

Hany01

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。