1. 程式人生 > >დ♂Hany01's Blog Space♂ღ

დ♂Hany01's Blog Space♂ღ

Description

輸入一個n*m的矩陣,矩陣的每一個元素都是一個整數,然後有q個詢問,每次詢問一個子矩陣的權值。矩陣的權值是這樣定義的,對於一個整數x,如果它在該矩陣中出現了p次,那麼它給該矩陣的權值就貢獻p2。

Solution

由於出現pp次的元素的貢獻是p2p^2,我們可以看做每一對相同的元素可以產生11的貢獻。

我們定一個SS,大概為4040。 對於出現次數大於SS的元素,由於這樣的元素個數不多,直接暴力搞。 對於小於SS的元素,我們兩兩配對,由於要求在矩形範圍內,有44個限制,所以是個四維偏序問題,將第一維排序,剩下的用三維樹狀陣列即可。

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 n = read(), m = read(); 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; q = read(); For(i, 1, q) { qry[i].x1 = read(), qry[i].y1 = read(), qry[i].x2 = read(), qry[i].y2 = read(); 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; }