제출 #207940

#제출 시각아이디문제언어결과실행 시간메모리
207940ToMmyDongRectangles (IOI19_rect)C++14
100 / 100
2936 ms345080 KiB
#include "rect.h" #pragma GCC optimize("Ofast") #pragma GCC target("avx,avx2,fma") #pragma GCC optimize("unroll-loops") #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<short,short> pii; #define ALL(i) i.begin(),i.end() #define X first #define Y second #define eb emplace_back #define SZ(i) int(i.size()) #ifdef tmd #define debug(...) fprintf(stderr,"%d (%s) = ",__LINE__,#__VA_ARGS__);_do(__VA_ARGS__); template<typename T> void _do (T &&x){cerr<<x<<endl;} template<typename T, typename ...S> void _do (T &&x, S &&...y) {cerr<<x<<",";_do(y...);} template<typename IT> ostream &printRng (IT bg, IT ed, ostream &os) { os<<"{"; for (IT it=bg; it!=ed; it++) { if (it!=bg) { os<<","; } os<<(*it); } return os<<"}"; } template<typename T> ostream &operator << (ostream &os, vector<T> &vec) { return printRng(vec.begin(), vec.end(), os); } template<typename T> ostream &operator << (ostream &os, pair<T,T> &vec) { return os<<"{"<<vec.first<<","<<vec.second<<"}"; } template<typename T> void pary (T bg, T ed) { printRng(bg,ed,cerr); cerr<<endl; } #else #define debug(...) #define pary(...) #endif // tmd const int MAXN = 2502; int n, m; int bit[MAXN]; void add (int x, int y) { for (x++;x<MAXN;x+=-x&x) { bit[x] += y; } } int sqry (int x) { int ret = 0; for (x++;x>0; x-=-x&x) { ret += bit[x]; } return ret; } vector<vector<int> > G; struct Edge { pii dt; int nxt; } edge[MAXN*MAXN*2]; int h[MAXN][MAXN], g[MAXN][MAXN], cnt; void addEdge (int x, int y, pii dt, int v[MAXN][MAXN]) { edge[cnt++] = {dt, v[x][y]}; v[x][y] = cnt - 1; } struct Node { short x; int nxt; } node[MAXN*MAXN*2]; int pa[MAXN][MAXN], ncnt; void addNode (int x, int y, short dt, int v[MAXN][MAXN]) { node[ncnt++] = {dt, v[x][y]}; v[x][y] = ncnt - 1; } int solve (int i, int j) { vector<pair<int,int> > qry, gg; for (int id=h[i][j]; id!=-1; id=edge[id].nxt) { qry.emplace_back(edge[id].dt); swap(qry.back().first, qry.back().second); } for (int id=g[j][i]; id!=-1; id=edge[id].nxt) { gg.emplace_back(edge[id].dt); } reverse(ALL(gg)); sort(qry.begin(), qry.end()); int res = 0; int idx = 0; vector<int> opr; int sum = 0; for (auto p : qry) { while (idx < int(gg.size()) && gg[idx].X <= p.X) { add(gg[idx].Y, 1); sum ++; opr.eb(gg[idx].Y); idx++; } res += sum - sqry(p.Y-1); } for (auto p : opr) { add(p, -1); } if (res) { debug(i, j, res); debug(qry); debug(gg); } return res; } void build (int res[MAXN][MAXN]) { memset(pa, -1, sizeof(pa)); ncnt = 0; vector<int> stk; for (int i=0; i<n; i++) { stk.clear(); for (int j=0; j<m; j++) { while (stk.size() && G[i][stk.back()] < G[i][j]) { if (stk.back() < j - 1) { addNode(stk.back(),j,i,pa); debug(stk.back(), j, i); } stk.pop_back(); } if (stk.size()) { if (stk.back() < j - 1) { debug(stk.back(), j, i); addNode(stk.back(),j,i,pa); } } while (stk.size() && G[i][stk.back()] == G[i][j]) { stk.pop_back(); } stk.eb(j); } } // debug("hf"); for (int l=0; l<m; l++) { for (int r=l+2; r<m; r++) { int len = 0; int ls = -1; for (int k=pa[l][r]; k!=-1; k=node[k].nxt) { int x = node[k].x; if (ls!=-1 && x+1!=ls) { len = 0; } len++; addEdge(x-1,l,{r-l-1, len},res); ls = x; } } } } vector<vector<int> > flip (vector<vector<int> > vec) { vector<vector<int> > res; for (int j=0; j<SZ(vec[0]); j++) { vector<int> cur; for (int i=0; i<SZ(vec); i++) { cur.emplace_back(vec[i][j]); } res.emplace_back(cur); } swap(n, m); return res; } long long count_rectangles(std::vector<std::vector<int> > a) { G = a; n = a.size(); m = a[0].size(); debug(n, m); memset(h, -1, sizeof(h)); memset(g, -1, sizeof(g)); build(h); G = flip(G); debug("FL"); build(g); G = flip(G); ll res = 0; for (int i=0; i<n; i++) { for (int j=0; j<m; j++) { res += solve(i, j); } } 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...