제출 #293273

#제출 시각아이디문제언어결과실행 시간메모리
293273rqiRectangles (IOI19_rect)C++14
59 / 100
5120 ms760580 KiB
#include "rect.h"
#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vpi;
 
const int MOD = 1000000007;
 
#define ins insert
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define all(x) begin(x), end(x)
 
const int mx = 2505;
int n, m;
 
set<int> ints[mx][mx];
 
vpi queries[mx][mx];
vpi updates[mx][mx];
 
set<pair<pi, pi>> rang; //l, r, leftval, rightval (outside range)
 
vpi getInts(vi a){
	// cout << "Q: ";
	// for(auto u: a) cout << u << " ";
	// cout << "\n";
 
	vpi res;
	
	rang.clear();
	rang.ins(mp(mp(0, sz(a)-1), mp(MOD, MOD)));
	vpi vals;
	for(int i = 0; i < sz(a); i++){
		vals.pb(mp(a[i], i));
	}
	sort(vals.rbegin(), vals.rend());
	for(int i = 0; i < sz(vals); i++){
		pair<pi, pi> b = *(prev(rang.lb(mp(mp(vals[i].s, MOD), mp(0, 0)))));
		//cout << i << "\n";
		assert(b.f.f <= vals[i].s && vals[i].s <= b.f.s);
		rang.erase(b);
		//if vals[i] is the max in range & if not on boundary
		if(vals[i].f < min(b.s.f, b.s.s) && 1 <= b.f.f && b.f.s <= sz(a)-2){
			res.pb(b.f);
		}
		//only divide if range added
		if(b.f.f <= vals[i].s-1){
			rang.ins(mp(mp(b.f.f, vals[i].s-1), mp(b.s.f, vals[i].f)));
		}
		if(vals[i].s+1 <= b.f.s){
			rang.ins(mp(mp(vals[i].s+1, b.f.s), mp(vals[i].f, b.s.s)));
		}
	}
 
	// cout << "R: ";
	// for(auto u: res) cout << "(" << u.f << " " << u.s << "), ";
	// cout << "\n";
	return res;
}
 
int val[mx];
vi curin;
 
void upd(int a, int v){
	if(v == 1) curin.pb(a);
	for(; a < mx; a+=a&-a) val[a]+=v;
}
 
int sum(int a){
	int res = 0;
	for(; a > 0; a-=a&-a) res+=val[a];
	return res;
}
 
int query(int a, int b){
	return sum(b)-sum(a-1);
}
 
void clearBIT(){
	for(auto u: curin){
		upd(u, -1);
	}
	curin.clear();
}
 
ll count_rectangles(vector<vi> a){
	n = sz(a);
	m = sz(a[0]);
	for(int i = 1; i+1 < n; i++){
		vi nums;
		for(int j = 0; j < m; j++){
			nums.pb(a[i][j]);
		}
		vpi a = getInts(nums);
		for(auto u: a){
			ints[i][u.f].ins(u.s);
		}
	}
 
	set<int> vals;
 
	for(int i = 1; i+1 < n; i++){
		for(int j = 1; j+1 < m; j++){
			vals = ints[i][j];
			for(auto u: vals){
				for(int K = i; K+1 < n; K++){
					if(!ints[K+1][j].count(u)){
						for(int k = i; k <= K; k++){
							queries[k][j].pb(mp(K, u));
							//cout << "Q: " << k << " " << j << " " << K << " " << u << "\n";
							ints[k][j].erase(u);
						}
						break;
					}
				}
			}
		}
	}
 
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			ints[i][j].clear();
		}
	}
 
	for(int j = 1; j+1 < m; j++){
		//cout << "j: " << j << "\n";
		vi nums;
		for(int i = 0; i < n; i++){
			nums.pb(a[i][j]);
		}
		vpi a = getInts(nums);
		// cout << "a: " << "\n";
		// for(auto u: a){
		// 	cout << u.f << " " << u.s << "\n";
		// }
		for(auto u: a){
			ints[u.f][j].ins(u.s);
		}
	}
 
	
	for(int j = 1; j+1 < m; j++){
		for(int i = 1; i+1 < n; i++){
			vals = ints[i][j];
			for(auto u: vals){
				for(int K = j; K+1 < m; K++){
					if(!ints[i][K+1].count(u)){
						for(int k = j; k <= K; k++){
							updates[i][k].pb(mp(u, K));
							//cout << "U: " << i << " " << k << " " << u << " " << K << "\n";
							//cout << i << " " << j << " " << k << "\n";
							ints[i][k].erase(u);
						}
						break;
					}
				}
			}
		}
	}
 
	ll ans = 0;
 
	for(int i = 1; i+1 < n; i++){
		for(int j = 1; j+1 < m; j++){
			sort(all(queries[i][j]));
			sort(all(updates[i][j]));
			int updind = 0;
			for(auto u: queries[i][j]){
				while(updind < sz(updates[i][j])){
					if(updates[i][j][updind].f <= u.f){
						upd(updates[i][j][updind].s, 1);
						updind++;
					}
					else break;
				}
				//if(query(u.s, 2504) > 0) cout << i << " " << j << "\n";
				ans+=query(u.s, 2504); //number of things >=
			}
			clearBIT();
		}
	}
 
	return ans;
}
#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...