답안 #1010832

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1010832 2024-06-29T12:14:45 Z Muaath_5 이상적인 도시 (IOI12_city) C++17
100 / 100
57 ms 14416 KB
#pragma GCC optimize("Ofast,O3,unroll-loops")
#include <bits/stdc++.h>
#define ll long long
#define pii pair<ll, ll>
#define X [0]
#define Y [1]
using namespace std;

const int MX = 1e5+5, MOD = 1'000'000'000,
	DX[] = {0,0,1,-1}, DY[] = {1,-1,0,0};
	
const ll INF = 1e15;


int n;
vector<vector<array<int, 2>>> nodes;
vector<array<int, 2>> a;

/*
1- Build nodes for each horizontal level (each node has an index)
2- Build edges by keeping a pointer
3- DP on trees, sum of all pairs
*/

vector<int> adj[MX];
ll cnt[MX], subdist[MX], dist[MX];
 map<int, array<int, 2>> nodemp;
 
void dfs(int node = 0, int par = -1)
{
	auto vv = nodemp[node];
	auto rng = nodes[vv X][vv Y];
	cnt[node] = rng Y - rng X + 1;
	for (int ch : adj[node])
		if (ch ^ par) {
			dfs(ch, node);
			cnt[node] += cnt[ch];
			subdist[node] += subdist[ch] + cnt[ch];
		}
}
 
void dfs2(int node = 0, int par = -1)
{
	for (int ch : adj[node])
		if (ch ^ par) {
			dist[ch] = (dist[node] - subdist[ch] - cnt[ch]) + (n - cnt[ch]);
			dfs2(ch, node);
		}
}

int solve()
{
	nodes.clear();
	sort(a.begin(), a.end());
	const int lvlcnt = a.back()[0] - a.front()[0] + 1;
	//cout << "===\n";
//	cout << lvlcnt;
	/*
	for (int i = 0; i < n; i++)
		cout << a[i][0] << ' ' << a[i][1] << '\n';
	*/
	nodes.resize(a.back()[0] - a.front()[0] + 1);
	int px = -1, py = -1;
	int idx = 0;
	for (int i = 0; i < n; i++) {
		if (px == a[i]X && py == a[i]Y-1) {
			nodes[a[i]X].back()Y = a[i]Y;
		}
		else {
			nodes[a[i]X].push_back({a[i]Y, a[i]Y});
			idx++;
		}
		px = a[i]X, py = a[i]Y;
	}
	
	
	int pref = 0;

	nodemp.clear();
	for (int j = 0; j < nodes[0].size(); j++)
		nodemp[j] = {0, j};
	for (int i = 0; i < MX; i++)
		i[adj].clear();
	
	for (int i = 1; i < lvlcnt; i++) {
		int pnt = 0;
		for (int j = 0; j < nodes[i].size(); j++) {
			nodemp[pref + nodes[i-1].size() + j] = {i, j};
			
			if (pnt > 0) pnt --;
			while (pnt < nodes[i-1].size() && nodes[i-1][pnt]Y < nodes[i][j]X)
				pnt++;
			while (pnt < nodes[i-1].size() && (nodes[i-1][pnt]X <= nodes[i][j]Y || nodes[i-1][pnt]Y <= nodes[i][j]Y)) {
				adj[pref + nodes[i-1].size() + j].push_back(pref + pnt);
				adj[pref + pnt].push_back(pref + nodes[i-1].size() + j);
				pnt++;	
			}
		}
		pref += nodes[i-1].size();
	}
	pref += nodes[lvlcnt-1].size();
	
	
	// for (int i = 0; i < pref; i++) {
		// cout << i << ": ";
		// for (int j : adj[i])
			// cout << j << ' ';
		// cout << '\n';
	// }
		
	
	// DP on trees
	
	memset(dist, 0, sizeof dist);
	memset(cnt, 0, sizeof cnt);
	memset(subdist, 0, sizeof subdist);
	
	ll sum = 0;
	
	dfs();
	dist[0] = subdist[0];
	dfs2();
	for (int i = 0; i < pref; i++) {
		auto [w, e] = nodemp[i];
		//cout << i << "# " << w << ": " << nodes[w][e]X << ' ' << nodes[w][e]Y << " " << n << " " << cnt[i]<<'\n';
		sum += (cnt[i]) * (n - cnt[i]); //dist[i];
		sum %= MOD;
		idx++;
	}
	
	return sum;
}

int DistanceSum(int n_, int x[], int y[]) {
	n = n_;
	a.reserve(n);
	for (int i = 0; i < n; i++)
		a.push_back({x[i], y[i]});
	int mnx = *min_element(x, x+n), mny = *min_element(y, y+n);
	
	for (int i = 0; i < n; i++)
		a[i]X -= mnx, a[i]Y -= mny;
	int h = solve();
	for (int i = 0; i < n; i++)
		swap(a[i][0], a[i][1]);
	
	int v = solve();
	//cout << "#: " << h << " " << v << '\n';
	return (h+v)%MOD;
}


#ifdef MUAATH_5

int main() {
  int tmp;
  int N, i;
  tmp = scanf("%d", &N);
  assert(tmp == 1);
  int *sq_x, *sq_y;
  sq_x = (int*) malloc(N * sizeof(int));
  sq_y = (int*) malloc(N * sizeof(int));
  for (i = 0; i < N; i++) {
    tmp = scanf("%d %d", &sq_x[i], &sq_y[i]);
    //assert(tmp == 2);
  }
  int ds = DistanceSum(N, sq_x, sq_y);
  printf("%d\n", ds);

}
#endif

Compilation message

city.cpp: In function 'int solve()':
city.cpp:80:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::array<int, 2> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   80 |  for (int j = 0; j < nodes[0].size(); j++)
      |                  ~~^~~~~~~~~~~~~~~~~
city.cpp:87:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::array<int, 2> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   87 |   for (int j = 0; j < nodes[i].size(); j++) {
      |                   ~~^~~~~~~~~~~~~~~~~
city.cpp:91:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::array<int, 2> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   91 |    while (pnt < nodes[i-1].size() && nodes[i-1][pnt]Y < nodes[i][j]X)
      |           ~~~~^~~~~~~~~~~~~~~~~~~
city.cpp:93:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::array<int, 2> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   93 |    while (pnt < nodes[i-1].size() && (nodes[i-1][pnt]X <= nodes[i][j]Y || nodes[i-1][pnt]Y <= nodes[i][j]Y)) {
      |           ~~~~^~~~~~~~~~~~~~~~~~~
city.cpp:124:8: warning: structured binding declaration set but not used [-Wunused-but-set-variable]
  124 |   auto [w, e] = nodemp[i];
      |        ^~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 4956 KB Output is correct
2 Correct 2 ms 5044 KB Output is correct
3 Correct 1 ms 4952 KB Output is correct
4 Correct 1 ms 5148 KB Output is correct
5 Correct 1 ms 4956 KB Output is correct
6 Correct 2 ms 5212 KB Output is correct
7 Correct 2 ms 4956 KB Output is correct
8 Correct 2 ms 4956 KB Output is correct
9 Correct 2 ms 4956 KB Output is correct
10 Correct 2 ms 4956 KB Output is correct
11 Correct 1 ms 4956 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4956 KB Output is correct
2 Correct 2 ms 4956 KB Output is correct
3 Correct 2 ms 5212 KB Output is correct
4 Correct 2 ms 5212 KB Output is correct
5 Correct 2 ms 5212 KB Output is correct
6 Correct 2 ms 5208 KB Output is correct
7 Correct 2 ms 5300 KB Output is correct
8 Correct 2 ms 5208 KB Output is correct
9 Correct 2 ms 5208 KB Output is correct
10 Correct 2 ms 5212 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 5724 KB Output is correct
2 Correct 7 ms 5812 KB Output is correct
3 Correct 16 ms 6236 KB Output is correct
4 Correct 16 ms 6428 KB Output is correct
5 Correct 38 ms 7640 KB Output is correct
6 Correct 32 ms 7768 KB Output is correct
7 Correct 33 ms 8020 KB Output is correct
8 Correct 39 ms 7516 KB Output is correct
9 Correct 39 ms 8016 KB Output is correct
10 Correct 41 ms 14416 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 6488 KB Output is correct
2 Correct 10 ms 6236 KB Output is correct
3 Correct 29 ms 8520 KB Output is correct
4 Correct 23 ms 7772 KB Output is correct
5 Correct 56 ms 11608 KB Output is correct
6 Correct 40 ms 9296 KB Output is correct
7 Correct 57 ms 11860 KB Output is correct
8 Correct 40 ms 9436 KB Output is correct
9 Correct 38 ms 8788 KB Output is correct
10 Correct 38 ms 8748 KB Output is correct