Submission #1172922

#TimeUsernameProblemLanguageResultExecution timeMemory
1172922InvMODPairs (IOI07_pairs)C++20
100 / 100
47 ms9032 KiB
#include<bits/stdc++.h> using namespace std; #define sz(v) (int)(v).size() #define all(v) (v).begin(), (v).end() using ll = long long; namespace Solve1D{ /* Normal two pointer or sweep line something */ void process() { int n,D,M; cin >> n >> D >> M; vector<int> a(n + 1); for(int i = 1; i <= n; i++){ cin >> a[i]; } sort(1 + all(a)); ll answer = 0; for(int i = 1, j = 1; i <= n; i++){ while(j < i && a[j] < a[i] - D) j++; answer = answer + 1ll * (i - j); } cout << answer << "\n"; } } struct BIT{ vector<int> bit; BIT(int n = 0): bit(n + 1) {} void update(int p, int val){ for(; p < sz(bit); p += (p & (-p))){ bit[p] += val; } return; } int get(int p){ int ans = 0; if(p <= 0) return ans; for(; p > 0; p -= (p & (-p))){ ans += bit[p]; } return ans; } int query(int l, int r){ return get(r) - get(l - 1); } }; namespace Solve2D{ /* xi <= xj, yi <= yj -> (1): d(i, j) = (xj - xi) + (yj - yi) = (xj + yj) - (xi + yi) xi >= xj, yi <= yj -> (2): d(i, j) = (xi - xj) + (yj - yi) = (xi - yi) - (xj - yj) xi <= xj, yi >= yj -> (3): d(i, j) = (xj - xi) + (yi - yj) = (xj - yj) - (xi - yi) xi >= xj, yi >= yj -> (4): d(i, j) = (xi - xj) + (yi - yj) = (xi + yi) - (xj - yj) Call d1_i = xi + yi, d2_i = xi - yi (1): d1_j - d1_i (2): d2_i - d2_j (3): d2_j - d2_i (4): d1_i - d1_j dist(i, j) = max( (1), (2), (3), (4) ) <= d for i we will need some j that: + d1_i - d <= d1_j <= d1_i + d + d2_i - d <= d2_j <= d2_i + d so now we fix d1_j >= d1_i - d && d1_j <= d1_i we will need d2_j to be in range (d2_i - d, d2_i + d) */ void process() { int n,D,M; cin >> n >> D >> M; vector<pair<int,int>> d; for(int i = 0; i < n; i++){ int a,b; cin >> a >> b; int d1 = a + b, d2 = a - b + M; // be careful with <= 0 d.push_back(make_pair(d1, d2)); } sort(all(d)); BIT bit(M * 2); ll answer = 0; for(int i = 0, j = 0; i < sz(d); i++){ while(j < i && d[j].first < d[i].first - D){ bit.update(d[j].second, -1); j++; } answer = answer + bit.query(d[i].second - D, min(d[i].second + D, M * 2)); bit.update(d[i].second, 1); } cout << answer << "\n"; } } namespace Solve3D{ /* we had: + d1_i - D <= d1_j <= d1_i + D + d2_i - D <= d2_j <= d2_i + D so now we will do the same for each 3D dimension a with D change in each 2 dimension that we want to calculate will will for each 3D dimension (1 -> a) and preprocess all conditions by prefix 2D d1 will be column and d2 will be row or it will be a rectangle that has: + x1 = d1_i - newD + y1 = d2_i - newD + x2 = d1_i + newD + y2 = d2_i + newD for dimension a = current, just remember every pairs will be count (twice + itself) // some solution will be count this dimension like what we do with 2D array or just (calculated - cnt(inside current dimension)) / 2 Time complexity: O(n * 75) */ void process() { int n,D,M; cin >> n >> D >> M; vector<vector<vector<int>>> pref(M + 1, vector<vector<int>>(M * 2 + 1, vector<int>(M * 2 + 1))); vector<vector<pair<int,int>>> Query(M + 1, vector<pair<int,int>>()); for(int i = 0; i < n; i++){ int a,b,c; cin >> a >> b >> c; int d1 = b + c, d2 = b - c + M; pref[a][d1][d2]++; //cout << a <<" " << d1 <<" " << d2 << "\n"; Query[a].push_back(make_pair(d1, d2)); } for(int i = 1; i <= M; i++){ for(int j = 1; j <= M * 2; j++){ for(int k = 1; k <= M * 2; k++){ pref[i][j][k] = pref[i][j - 1][k] + pref[i][j][k - 1] -pref[i][j - 1][k - 1] + pref[i][j][k]; } } } ll answer = 0; for(int i = 1; i <= M; i++){ for(int a = 1; a <= i; a++){ int nD = D - (i - a); if(nD < 0) continue; auto qpref_sum = [&](int x1, int y1, int x2, int y2) -> int{ return pref[a][x2][y2] - pref[a][x2][y1 - 1] - pref[a][x1 - 1][y2] + pref[a][x1 - 1][y1 - 1]; }; ll calc = 0; for(pair<int,int>& cur_q : Query[i]){ int x1 = max(1, cur_q.first - nD); int x2 = min(M * 2, cur_q.first + nD); int y1 = max(1, cur_q.second - nD); int y2 = min(M * 2, cur_q.second + nD); //cout << x1 <<" " << y1 <<" " << x2 <<" " << y2 << "\n"; calc = calc + 1ll * qpref_sum(x1, y1, x2, y2); } calc = (a == i ? (calc - sz(Query[i])) / 2 : calc); answer = answer + calc; } } cout << answer << "\n"; } } void solve() { int B; cin >> B; if(B == 1) Solve1D::process(); if(B == 2) Solve2D::process(); if(B == 3) Solve3D::process(); } int32_t main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define name "InvMOD" if(fopen(name".INP", "r")){ freopen(name".INP", "r", stdin); freopen(name".OUT", "w", stdout); } solve(); return 0; }

Compilation message (stderr)

pairs.cpp: In function 'int32_t main()':
pairs.cpp:220:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  220 |         freopen(name".INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
pairs.cpp:221:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  221 |         freopen(name".OUT", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#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...
#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...