#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |