답안 #154464

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
154464 2019-09-22T03:17:25 Z liwi Rectangles (IOI19_rect) C++14
23 / 100
2537 ms 556812 KB
#include "rect.h"

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;

#define scan(x) do{while((x=getchar())<'0'); for(x-='0'; '0'<=(_=getchar()); x=(x<<3)+(x<<1)+_-'0');}while(0)
char _;
#define complete_unique(a) a.erase(unique(a.begin(),a.end()),a.end())
#define all(a) a.begin(),a.end()
#define println printf("\n");
#define readln(x) getline(cin,x);
#define pb push_back
#define endl "\n"
#define INT_INF 0x3f3f3f3f
#define LL_INF 0x3f3f3f3f3f3f3f3f
#define MOD 1000000007
#define MOD2 1494318097
#define SEED 131
#define mp make_pair
#define fastio cin.tie(0); cin.sync_with_stdio(0);

#define MAXN 2505

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unordered_map<int,int> umii;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef pair<ll,ll> pll;
typedef pair<int,pii> triple;
typedef int8_t byte;

mt19937 g1(time(0));

int randint(int a, int b){return uniform_int_distribution<int>(a, b)(g1);}
ll randlong(ll a,ll b){return uniform_int_distribution<long long>(a, b)(g1);}

ll gcd(ll a, ll b){return b == 0 ? a : gcd(b, a % b);}
ll lcm(ll a, ll b){return a*b/gcd(a,b);}
ll fpow(ll  b, ll exp, ll mod){if(exp == 0) return 1;ll t = fpow(b,exp/2,mod);if(exp&1) return t*t%mod*b%mod;return t*t%mod;}
ll divmod(ll i, ll j, ll mod){i%=mod,j%=mod;return i*fpow(j,mod-2,mod)%mod;}

int num_rows,num_cols,arr[MAXN][MAXN],bit[MAXN],cnt[MAXN][MAXN],ans;
pii dq[MAXN]; int l,r;
vector<pii> row_dp[MAXN][MAXN],col_dp[MAXN][MAXN];
vector<pair<pii,int>> dep[MAXN];
//vector<pii> rows[MAXN],cols[MAXN];
//vector<int> h_segs[MAXN][MAXN],v_segs[MAXN][MAXN];
//vector<int> r_range[MAXN][MAXN],v_range[MAXN][MAXN];

inline void update(int pos, int val){
	for(int i=pos; i<=num_cols; i+=i&-i)
		bit[i]+=val;
}

inline int query(int pos){
	int res = 0;
	for(int i=pos; i>0; i-=i&-i)
		res+=bit[i];
	return res;
}

inline void init_rows(){
//	memset(cnt,0,sizeof cnt);
	for(int i=2; i<num_rows; i++){
		l = 1, r = 0;
		for(int k=1; k<=num_cols; k++){
			while(r-l+1 > 0 && dq[r].first < arr[i][k]) r--;
			int lft = (r-l+1>0?dq[r].second:INT_INF);
			if(lft < k-1 && (row_dp[lft+1][k-1].empty() || row_dp[lft+1][k-1].back().first != i))
				row_dp[lft+1][k-1].pb(mp(i,i)), cnt[lft+1][k-1]++; //rows[i].pb(mp(lft+1,k-1));
			while(r-l+1 > 0 && dq[r].first == arr[i][k]) r--;
			dq[++r] = mp(arr[i][k],k);
		}
		l = 1, r = 0;
		for(int k=num_cols; k>=1; k--){
			while(r-l+1 > 0 && dq[r].first < arr[i][k]) r--;
			int rgt = (r-l+1>0?dq[r].second:-INT_INF);
			if(rgt > k+1 && (row_dp[k+1][rgt-1].empty() || row_dp[k+1][rgt-1].back().first != i))
				row_dp[k+1][rgt-1].pb(mp(i,i)), cnt[k+1][rgt-1]++; //rows[i].pb(mp(k+1,rgt-1));
			while(r-l+1 > 0 && dq[r].first == arr[i][k]) r--;
			dq[++r] = mp(arr[i][k],k);
		}
	}
}

inline void init_cols(){
	memset(cnt,0,sizeof cnt);
	for(int i=2; i<num_cols; i++){
		l = 1, r = 0;
		for(int k=1; k<=num_rows; k++){
			while(r-l+1 > 0 && dq[r].first < arr[k][i]) r--;
			int lft = (r-l+1>0?dq[r].second:INT_INF);
			if(lft < k-1 && (col_dp[lft+1][k-1].empty() || col_dp[lft+1][k-1].back().first != i))
				col_dp[lft+1][k-1].pb(mp(i,i)), cnt[lft+1][k-1]++; //cols[i].pb(mp(lft+1,k-1));
			while(r-l+1 > 0 && dq[r].first == arr[k][i]) r--;
			dq[++r] = mp(arr[k][i],k);
		}
		l = 1, r = 0;
		for(int k=num_rows; k>=1; k--){
			while(r-l+1 > 0 && dq[r].first < arr[k][i]) r--;
			int rgt = (r-l+1>0?dq[r].second:-INT_INF);
			if(rgt > k+1 && (col_dp[k+1][rgt-1].empty() || col_dp[k+1][rgt-1].back().first != i))
				col_dp[k+1][rgt-1].pb(mp(i,i)), cnt[k+1][rgt-1]++; //cols[i].pb(mp(k+1,rgt-1));
			while(r-l+1 > 0 && dq[r].first == arr[k][i]) r--;
			dq[++r] = mp(arr[k][i],k);
		}
	}
}

inline void calc_hor_dp(){
//	for(int i=2; i<num_rows; i++){
//		sort(all(rows[i])); complete_unique(rows[i]);
//		for(pii check:rows[i]){
//			h_segs[check.first][check.second].pb(i);
////			r_range[i][check.first].pb(check.second);
//		}
//		rows[i].clear();
//	}
	for(int l=2; l<=num_cols-1; l++){
		for(int r=l; r<=num_cols-1; r++){
			vector<pii> &nums = row_dp[l][r];
			if(cnt[l][r] == 0) continue;
//			sort(all(nums)); complete_unique(nums);
//			vector<pii> t;
			int lst = 0;
			for(int i=1; i<cnt[l][r]; i++){
				if(nums[i].first == nums[i-1].first+1) continue;
				for(int k=nums[lst].first; k<=nums[i-1].first; k++)
					dep[nums[i-1].first-k+1].pb(mp(mp(k,l),r));
//					row_dp[k][l].pb(mp(nums[i-1].first-k+1,r));
				lst = i;
			}
			for(int k=nums[lst].first; k<=nums[cnt[l][r]-1].first; k++)
				dep[nums[cnt[l][r]-1].first-k+1].pb(mp(mp(k,l),r));
//				row_dp[k][l].pb(mp(nums[cnt[l][r]-1].first-k+1,r));
			nums.clear();
		}
	}
	for(int i=1; i<=num_rows; i++){
		for(pair<pii,int> check:dep[i])
			row_dp[check.first.first][check.first.second].pb(mp(i,check.second));
	}
//	for(int l=2; l<=num_cols-1; l++){
//		for(int r=l; r<=num_cols-1; r++){
//			reverse(all(row_dp[l][r]));
//			while(cnt[l][r]--) row_dp[l][r].pop_back();
//			reverse(all(row_dp[l][r]));
//		}
//	}
}

inline void calc_col_dp(){
//	for(int i=2; i<num_cols; i++){
//		sort(all(cols[i])); complete_unique(cols[i]);
//		for(pii check:cols[i]){
//			v_segs[check.first][check.second].pb(i);
////			v_range[check.first][i].pb(check.second);
//		}
//		cols[i].clear();
//	}
	for(int l=2; l<=num_rows-1; l++){
		for(int r=l; r<=num_rows-1; r++){
			vector<pii> &nums = col_dp[l][r];
			if(cnt[l][r] == 0) continue;
//			sort(all(nums)); complete_unique(nums);
			int lst = 0;
			for(int i=1; i<cnt[l][r]; i++){
				if(nums[i].first == nums[i-1].first+1) continue;
				for(int k=nums[lst].first; k<=nums[i-1].first; k++)
					col_dp[l][k].pb(mp(r,nums[i-1].first));
				lst = i;
			}
			for(int k=nums[lst].first; k<=nums[cnt[l][r]-1].first; k++)
				col_dp[l][k].pb(mp(r,nums[cnt[l][r]-1].first));
		}
	}
	for(int l=2; l<=num_cols-1; l++){
		for(int r=l; r<=num_cols-1; r++){
			reverse(all(col_dp[l][r]));
//			while(cnt[l][r]--) col_dp[l][r].pop_back();
//			reverse(all(col_dp[l][r]));
		}
	}
}

ll count_rectangles(vector<vector<int>> a){
	ans = 0, num_rows = (int)a.size(), num_cols = (int)a[0].size();
	for(int i=0; i<a.size(); i++)
		for(int k=0; k<a[i].size(); k++)
			arr[i+1][k+1] = a[i][k];
	init_rows(); calc_hor_dp();
	init_cols(); calc_col_dp();
	for(int i=2; i<num_rows; i++){
		for(int k=2; k<num_cols; k++){
//			sort(all(row_dp[i][k]));
//			sort(all(col_dp[i][k]));
			int ptr = 0, res = 0, cc = 0;
			for(int v=0; v<row_dp[i][k].size(); v++){
//				pii curr = row_dp[i][k][v];
				while(ptr < col_dp[i][k].size()-cnt[i][k] && col_dp[i][k][ptr].first-i+1 <= row_dp[i][k][v].first){
//					assert(col_dp[i][k][ptr].second>=k);
					update(col_dp[i][k][ptr].second-k+1,1);
					ptr++, cc++;
				}
				res+=cc-query(row_dp[i][k][v].second-k);
			}
			while(ptr--){
				if(ptr == -1) break;
				update(col_dp[i][k][ptr].second-k+1,-1);
			}
			ans+=res;
		}
	}
	return ans;
}

Compilation message

rect.cpp: In function 'll count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:195:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0; i<a.size(); i++)
               ~^~~~~~~~~
rect.cpp:196:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int k=0; k<a[i].size(); k++)
                ~^~~~~~~~~~~~
rect.cpp:205:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for(int v=0; v<row_dp[i][k].size(); v++){
                 ~^~~~~~~~~~~~~~~~~~~~
rect.cpp:207:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     while(ptr < col_dp[i][k].size()-cnt[i][k] && col_dp[i][k][ptr].first-i+1 <= row_dp[i][k][v].first){
           ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 293 ms 319716 KB Output is correct
2 Correct 292 ms 319884 KB Output is correct
3 Correct 296 ms 319864 KB Output is correct
4 Correct 295 ms 319888 KB Output is correct
5 Correct 299 ms 319864 KB Output is correct
6 Incorrect 292 ms 319992 KB Output isn't correct
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 293 ms 319716 KB Output is correct
2 Correct 292 ms 319884 KB Output is correct
3 Correct 296 ms 319864 KB Output is correct
4 Correct 295 ms 319888 KB Output is correct
5 Correct 299 ms 319864 KB Output is correct
6 Incorrect 292 ms 319992 KB Output isn't correct
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 293 ms 319716 KB Output is correct
2 Correct 292 ms 319884 KB Output is correct
3 Correct 296 ms 319864 KB Output is correct
4 Correct 295 ms 319888 KB Output is correct
5 Correct 299 ms 319864 KB Output is correct
6 Incorrect 292 ms 319992 KB Output isn't correct
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 293 ms 319716 KB Output is correct
2 Correct 292 ms 319884 KB Output is correct
3 Correct 296 ms 319864 KB Output is correct
4 Correct 295 ms 319888 KB Output is correct
5 Correct 299 ms 319864 KB Output is correct
6 Incorrect 292 ms 319992 KB Output isn't correct
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 314 ms 320236 KB Output is correct
2 Correct 311 ms 320120 KB Output is correct
3 Correct 316 ms 319800 KB Output is correct
4 Correct 293 ms 319692 KB Output is correct
5 Correct 314 ms 319992 KB Output is correct
6 Correct 315 ms 320040 KB Output is correct
7 Correct 317 ms 319980 KB Output is correct
8 Correct 319 ms 319940 KB Output is correct
9 Correct 375 ms 319960 KB Output is correct
10 Correct 338 ms 319864 KB Output is correct
11 Correct 342 ms 319880 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 294 ms 319736 KB Output is correct
2 Correct 1151 ms 426696 KB Output is correct
3 Correct 2340 ms 552596 KB Output is correct
4 Correct 2426 ms 554540 KB Output is correct
5 Correct 2537 ms 556812 KB Output is correct
6 Correct 548 ms 362088 KB Output is correct
7 Correct 754 ms 391140 KB Output is correct
8 Correct 715 ms 397688 KB Output is correct
9 Correct 292 ms 319736 KB Output is correct
10 Correct 331 ms 319676 KB Output is correct
11 Correct 349 ms 319864 KB Output is correct
12 Correct 342 ms 319992 KB Output is correct
13 Correct 348 ms 319816 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 293 ms 319716 KB Output is correct
2 Correct 292 ms 319884 KB Output is correct
3 Correct 296 ms 319864 KB Output is correct
4 Correct 295 ms 319888 KB Output is correct
5 Correct 299 ms 319864 KB Output is correct
6 Incorrect 292 ms 319992 KB Output isn't correct
7 Halted 0 ms 0 KB -