Submission #532139

#TimeUsernameProblemLanguageResultExecution timeMemory
532139wiwihoSandcastle 2 (JOI22_ho_t5)C++14
100 / 100
739 ms16624 KiB
#include <bits/stdc++.h> #include <bits/extc++.h> #define StarBurstStream ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); #define iter(a) a.begin(), a.end() #define riter(a) a.rbegin(), a.rend() #define lsort(a) sort(iter(a)) #define gsort(a) sort(riter(a)) #define pb(a) push_back(a) #define eb(a) emplace_back(a) #define pf(a) push_front(a) #define ef(a) emplace_front(a) #define pob pop_back() #define pof pop_front() #define mp(a, b) make_pair(a, b) #define F first #define S second #define mt make_tuple #define gt(t, i) get<i>(t) #define tomax(a, b) ((a) = max((a), (b))) #define tomin(a, b) ((a) = min((a), (b))) #define topos(a) ((a) = (((a) % MOD + MOD) % MOD)) #define uni(a) a.resize(unique(iter(a)) - a.begin()) #define printv(a, b) {bool pvaspace=false; \ for(auto pva : a){ \ if(pvaspace) b << " "; pvaspace=true;\ b << pva;\ }\ b << "\n";} using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef unsigned long long ull; typedef long double ld; using pii = pair<int, int>; using pll = pair<ll, ll>; using pdd = pair<ld, ld>; using tiii = tuple<int, int, int>; const ll MOD = 1000000007; const ll MAX = 10000001; template<typename A, typename B> ostream& operator<<(ostream& o, pair<A, B> p){ return o << '(' << p.F << ',' << p.S << ')'; } ll ifloor(ll a, ll b){ if(b < 0) a *= -1, b *= -1; if(a < 0) return (a - b + 1) / b; else return a / b; } ll iceil(ll a, ll b){ if(b < 0) a *= -1, b *= -1; if(a > 0) return (a + b - 1) / b; else return a / b; } vector<pii> dir = {mp(-1, 0), mp(0, 1), mp(1, 0), mp(0, -1)}; struct sum2d{ vector<vector<ll>> a; void init(vector<vector<ll>>& t){ a = t; int n = a.size(), m = a[0].size(); n--; m--; for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++) a[i][j] += a[i][j - 1]; } for(int j = 1; j <= m; j++){ for(int i = 1; i <= n; i++) a[i][j] += a[i - 1][j]; } } ll query(int x1, int x2, int y1, int y2){ if(x1 > x2 || y1 > y2) return 0; return a[x2][y2] - a[x1 - 1][y2] - a[x2][y1 - 1] + a[x1 - 1][y1 - 1]; } }; int n, m; vector<sum2d> diff; vector<vector<int>> a; void build_diff(int msk){ vector<vector<ll>> t(n + 1, vector<ll>(m + 1)); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ ll nxt = 0; bool sp = true; for(int k = 0; k < 4; k++){ if(!(1 << k & msk)) continue; int nx = i + dir[k].F, ny = j + dir[k].S; if(a[nx][ny] > a[i][j]) sp = false; else nxt = max(nxt, (ll)a[nx][ny]); } nxt = a[i][j] - nxt; if(sp) nxt += MAX - a[i][j]; t[i][j] = nxt; } } diff[msk].init(t); } ll ans = 0; ll colleft(int u, int d, int i){ if(u == d){ return diff[0b0100].query(u, d, i, i); } ll ans = diff[0b0110].query(u, u, i, i) + diff[0b1100].query(d, d, i, i); ans += diff[0b1110].query(u + 1, d - 1, i, i); return ans; } ll colmid(int u, int d, int i){ if(u == d){ return diff[0b0101].query(u, d, i, i); } ll ans = diff[0b0111].query(u, u, i, i) + diff[0b1101].query(d, d, i, i); ans += diff[0b1111].query(u + 1, d - 1, i, i); return ans; } ll colright(int u, int d, int i){ if(u == d){ return diff[0b0001].query(u, d, i, i); } ll ans = diff[0b0011].query(u, u, i, i) + diff[0b1001].query(d, d, i, i); ans += diff[0b1011].query(u + 1, d - 1, i, i); return ans; } ll coltwo(int u, int d, int i){ if(u == d){ return diff[0b0000].query(u, d, i, i); } ll ans = diff[0b0010].query(u, u, i, i) + diff[0b1000].query(d, d, i, i); ans += diff[0b1010].query(u + 1, d - 1, i, i); return ans; } void solve(int u, int d){ map<ll, ll> tmp; ll pre = 0; //cerr << "solve " << u << " " << d << "\n"; for(int i = 1; i <= m; i++){ if(coltwo(u, d, i) == MAX){ //cerr << "two " << i << "\n"; ans++; } if(tmp.find(MAX - pre - colright(u, d, i)) != tmp.end()){ //cerr << "ok " << i << "\n"; ans += tmp[MAX - pre - colright(u, d, i)]; } //cerr << "test " << i << " " << pre + colright(u, d, i) << " " << MAX - pre - colright(u, d, i) << " "; pre += colmid(u, d, i); tmp[- pre + colleft(u, d, i)]++; //cerr << -pre + colleft(u, d, i) << "\n"; } } int main(){ StarBurstStream reverse(iter(dir)); cin >> n >> m; a.resize(n + 2, vector<int>(m + 2)); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ cin >> a[i][j]; } } if(n > m){ vector<vector<int>> ta(m + 2, vector<int>(n + 2)); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++) ta[j][i] = a[i][j]; } a = ta; swap(n, m); } diff.resize(16); for(int i = 0; i < 16; i++) build_diff(i); /*for(int i = 1; i <= m; i++){ cerr << "diff " << i << " "; for(int j = 0; j < 16; j++){ cerr << diff[j].query(1, 1, i, i) << " "; } cerr<< "\n"; }*/ for(int i = 1; i <= n; i++){ for(int j = i; j <= n; j++) solve(i, j); } cout << ans << "\n"; return 0; }
#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...