Submission #39106

#TimeUsernameProblemLanguageResultExecution timeMemory
3910614kgIdeal city (IOI12_city)C++11
32 / 100
1000 ms50980 KiB
#include <map> #include <algorithm> #include <vector> #include <stdio.h> #define N 100000 #define MOD 1000000000 #define INF 2147483646 #define min2(x,y) (x<y?x:y) using namespace std; int n, tree1_len, tree2_len, tree1_cnt[N], tree2_cnt[N]; long long out; pair<int,long long> t_save[N]; vector<int> tree1[N], tree2[N]; map<pair<int, int>, int > tree1_NUM, tree2_NUM; map<pair<int, int>, bool> M, tree1_link, tree2_link; pair<int, long long> count_tree1(int lev, int up) { long long cnt = 0, t = 0; pair<int, long long> temp; // printf(" IN %d\n ", lev); for (auto i : tree1[lev]) if (i != up) { t_save[i] = temp = count_tree1(i, lev); // out += (long long)temp.first*t, out %= MOD; t += temp.second, cnt += temp.first; } for (auto i : tree1[lev]) if (i != up) { out += (long long)t_save[i].first*(t-t_save[i].second), out %= MOD; } out += (long long)tree1_cnt[lev] * t, out %= MOD; cnt += (long long)tree1_cnt[lev]; return{ (int)cnt,t + cnt }; } pair<int, long long> count_tree2(int lev, int up) { long long cnt = 0, t = 0; pair<int, long long> temp; //printf(" IN %d\n ", lev); for (auto i : tree2[lev]) if (i != up) { //printf("%d -> %d\n", lev, i); t_save[i] = temp = count_tree2(i, lev); // out += (long long)temp.first*t, out %= MOD; t += temp.second, cnt += temp.first; } for (auto i : tree2[lev]) if (i != up) { //printf("%d -> %d\n", lev, i); out += (long long)t_save[i].first*(t-t_save[i].second), out %= MOD; // t += temp.second, cnt += temp.first; } out += (long long)tree2_cnt[lev] * t, out %= MOD; cnt += (long long)tree2_cnt[lev]; return{ (int)cnt,t + cnt }; } int DistanceSum(int _n, int *X, int *Y) { n = _n; int x_min=INF, y_min=INF; for (int i = 0; i < n; i++) x_min = min2(x_min, X[i]), y_min = min2(y_min, Y[i]); for (int i = 0; i < n; i++) M[{X[i] - x_min, Y[i] - y_min}] = true; for (int i = 0; i < n; i++) { int tx = X[i] - x_min, ty = Y[i] - y_min; int ttx = tx, tty = ty; if (!M[{tx, ty - 1}]) { tree1_len++; while (M[{tx, ty}]) { tree1_cnt[tree1_len]++; tree1_NUM[{tx, ty}] = tree1_len; ty++; } } tx = ttx, ty = tty; if (!M[{tx - 1, ty}]) { tree2_len++; while (M[{tx, ty}]) { tree2_cnt[tree2_len]++; tree2_NUM[{tx, ty}] = tree2_len; tx++; } } } int x, y; for (int i = 0; i < n; i++) { int tx = X[i] - x_min, ty = Y[i] - y_min; //printf("(%d %d)%d - %d\n", X[i],Y[i],i, tree1_NUM[{tx,ty}]); x = tree1_NUM[{tx, ty}], y = tree1_NUM[{tx + 1, ty}]; if (M[{tx + 1, ty}] && tree1_link[{x, y}] == false) { // printf("! %d %d\n",x,y); tree1_link[{x, y}] = true, tree1_link[{y, x}] = true; tree1[x].push_back(y), tree1[y].push_back(x); } x = tree1_NUM[{tx, ty}], y = tree1_NUM[{tx - 1, ty}]; if (M[{tx - 1, ty}] && tree1_link[{x, y}] == false) { // printf("! %d %d\n",x,y); tree1_link[{x, y}] = true, tree1_link[{y, x}] = true; tree1[x].push_back(y), tree1[y].push_back(x); } x = tree2_NUM[{tx, ty}], y = tree2_NUM[{tx, ty + 1}]; if (M[{tx, ty + 1}] && tree2_link[{x, y}] == false) { tree2_link[{x, y}] = true, tree2_link[{y, x}] = true; tree2[x].push_back(y), tree2[y].push_back(x); } x = tree2_NUM[{tx, ty}], y = tree2_NUM[{tx, ty - 1}]; if (M[{tx, ty - 1}] && tree2_link[{x, y}] == false) { tree2_link[{x, y}] = true, tree2_link[{y, x}] = true; tree2[x].push_back(y), tree2[y].push_back(x); } } count_tree1(1, 0), count_tree2(1, 0); // printf("%d %d ", tree1_len, tree2_len); return (int)out; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...