Submission #143810

#TimeUsernameProblemLanguageResultExecution timeMemory
143810aintaRectangles (IOI19_rect)C++17
100 / 100
3590 ms803572 KiB
#include "rect.h" #include <cstdio> #include <algorithm> #include <vector> using namespace std; int n, m, w[2600][2600], T[2600]; vector<int>Right[2600][2600], Down[2600][2600]; int st[2600], RR[2600], LL[2600]; void PreCalc(int n) { int i, top = 0; for (i = 1; i <= n; i++)RR[i] = LL[i] = 0; for (i = 1; i <= n; i++) { while (top && T[st[top]] <= T[i]) { RR[st[top]] = i; top--; } st[++top] = i; } top = 0; for (i = n; i >= 1; i--) { while (top && T[st[top]] <= T[i]) { LL[st[top]] = i; top--; } st[++top] = i; } } int last[2600][2600], CC[2600][2600]; int lastH[2600], CH[2600]; struct point { int x, y, ck; bool operator<(const point &p)const { return x < p.x; } }U[10100]; int BIT[2600]; void Add(int a, int b) { while (a <= m) { BIT[a] += b; a += (a&-a); } } int Sum(int a) { int r = 0; while (a) { r += BIT[a]; a -= (a&-a); } return r; } long long count_rectangles(std::vector<std::vector<int> > a) { n = a.size(); m = a[0].size(); int i, j; for (i = 0; i < n; i++)for (j = 0; j < m; j++)w[i + 1][j + 1] = a[i][j]; for (i = 1; i <= n; i++) { for (j = 1; j <= m; j++) { T[j] = w[i][j]; } PreCalc(m); for (j = 1; j <= m; j++) { if (RR[j] && RR[j]>j+1)Right[i][j+1].push_back(RR[j]-1); if (LL[j] && LL[j]<j-1 && RR[LL[j]] != j)Right[i][LL[j] + 1].push_back(j - 1); } } for (i = 1; i <= m; i++) { for (j = 1; j <= n; j++) { T[j] = w[j][i]; } PreCalc(n); for (j = 1; j <= n; j++) { if (RR[j] && RR[j] > j + 1)Down[j + 1][i].push_back(RR[j] - 1); if (LL[j] && LL[j] < j - 1 && RR[LL[j]] != j)Down[LL[j] + 1][i].push_back(j - 1); } } long long res = 0; for (i = n; i >= 1; i--) { for (j = 1; j <= n; j++)lastH[j] = CH[j] = 0; for (j = m; j >= 1; j--) { for (auto &t : Right[i][j]) { if (last[j][t] != i + 1)CC[j][t] = 0; CC[j][t]++; last[j][t] = i; } for (auto &t : Down[i][j]) { if (lastH[t] != j + 1)CH[t]=0; CH[t]++; lastH[t] = j; } int cnt = 0; for (auto &t : Right[i][j]) { U[cnt++] = { i,t,1 }; U[cnt++] = { i + CC[j][t],t,-1 }; } sort(U, U + cnt); sort(Down[i][j].begin(), Down[i][j].end()); int pv = 0; for (auto &t : Down[i][j]) { while (pv < cnt && U[pv].x <= t) { Add(U[pv].y, U[pv].ck); pv++; } res += Sum(j + CH[t] - 1); } while (pv < cnt) { Add(U[pv].y, U[pv].ck); pv++; } } } return res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...