#include <bits/stdc++.h>
#define pb push_back
using namespace std;
struct SegTree1d
{
int n;
vector<int> data, left, right;
SegTree1d(int n) : n(n), data(1, 0), left(1, -1), right(1, -1) {}
void cc(int index)
{
if (left[index] == -1)
{
left[index] = data.size();
data.pb(0);
left.pb(-1);
right.pb(-1);
}
if (right[index] == -1)
{
right[index] = data.size();
data.pb(0);
left.pb(-1);
right.pb(-1);
}
}
void update(int l, int r, int index, int i, int val)
{
if (i >= r || l > i)
return;
if (l + 1 == r)
{
data[index] += val;
return;
}
cc(index);
int m = l+r>>1;
update(l, m, left[index], i, val);
update(m, r, right[index], i, val);
data[index] = data[left[index]] + data[right[index]];
}
int get(int l, int r, int index, int ss, int ee)
{
if (ss >= r || l >= ee)
return 0;
if (ee >= r && l >= ss)
return data[index];
int m = l+r>>1;
int lres = 0, rres = 0;
if (left[index] != -1)
lres = get(l, m, left[index], ss, ee);
if (right[index] != -1)
rres = get(m, r, right[index], ss, ee);
return lres + rres;
}
void update(int i, int val) { update(0, n, 0, i, val ); }
int get(int ss, int ee) { return get(0, n, 0, ss, ee); }
};
void solve1d()
{
int n, d, m;
cin >> n >> d >> m;
SegTree1d st(m);
vector<int> v(n);
for (int& i : v)
{
cin >> i;
i--;
st.update(i, 1);
}
int64_t encounters = 0;
for (int i : v)
encounters += st.get(i-d, i+d+1) - 1;
cout << (encounters / 2) << "\n";
}
struct SegTree2d
{
int ll, rr, uu, dd;
vector<int> data;
vector<int> left, right;
vector<int> root;
vector<int> down, up;
SegTree2d (int ll, int rr, int dd, int uu) : ll(ll), rr(rr), uu(uu), dd(dd), root(1, -1), up(1, -1), down(1, -1) {}
int create_x()
{
int res = data.size();
data.pb(0);
left.pb(-1);
right.pb(-1);
assert(res != -1);
return res;
}
int create_y()
{
int res = root.size();
root.pb(-1);
down.pb(-1);
up.pb(-1);
assert(res != -1);
return res;
}
void update_row(int l, int r, int index, int x, int val)
{
if (l + 1 == r)
{
data[index] += val;
return;
}
int m = l+r>>1;
if (m > x)
{
if (left[index] == -1)
{
int tmp = create_x();
left[index] = tmp;
}
assert(left[index] != -1);
update_row(l, m, left[index], x, val);
}
else
{
if (right[index] == -1)
{
int tmp = create_x();
right[index] = tmp;
}
assert(right[index] != -1);
update_row(m, r, right[index], x, val);
}
data[index] = 0;
if (left[index] != -1)
data[index] += data[left[index]];
if (right[index] != -1)
data[index] += data[right[index]];
}
void update_grid(int d, int u, int index, int x, int y, int val)
{
if (y >= u || d > y)
return;
if (root[index] == -1)
{
int tmp = create_x();
root[index] = tmp;
}
assert(root[index] != -1);
update_row(ll, rr, root[index], x, val);
if (d + 1 == u)
return;
int m = d+u>>1;
if (m > y)
{
if (down[index] == -1)
{
int tmp = create_y();
down[index] = tmp;;
}
assert(down[index] != -1);
update_grid(d, m, down[index], x, y, val);
}
else
{
if (up[index] == -1)
{
int tmp = create_y();
up[index] = tmp;
}
assert(up[index] != -1);
update_grid(m, u, up[index], x, y, val);
}
}
int get_row(int l, int r, int index, int xs, int xe)const
{
if (xs >= r || l >= xe || index == -1)
return 0;
if (xe >= r && l >= xs)
return data[index];
int m = l+r>>1;
int lres = get_row(l, m, left[index], xs, xe);
int rres = get_row(m, r, right[index], xs, xe);
return lres + rres;
}
int get_grid(int d, int u, int index, int xs, int xe, int ys, int ye)const
{
if (ys >= u || d >= ye || index == -1)
return 0;
if (ye >= u && d >= ys)
return get_row(ll, rr, root[index], xs, xe);
int m = d+u>>1;
int dres = get_grid(d, m, down[index], xs, xe, ys, ye);
int ures = get_grid(m, u, up[index], xs, xe, ys, ye);
return dres + ures;
}
void update(int x, int y, int val) { update_grid(dd, uu, 0, x, y, val); }
int get(int xs, int xe, int ys, int ye)const { return get_grid(dd, uu, 0, xs, xe, ys, ye); }
void clear()
{
for (int& i : data) i = 0;
}
};
const int BOTTOM_LEFT = 0;
void solve2d()
{
int n, d, m;
cin >> n >> d >> m;
vector<array<int, 2>> v(n);
//SegTree2d st[] = {SegTree2d(0, m, -2*m, 2*m), SegTree2d(0, m, -2*m, 2*m), SegTree2d(0, m, -2*m, 2*m), SegTree2d(0, m, -2*m, 2*m) } ;
SegTree2d st(0, m, -2*m, 2*m);
for (auto& [x, y] : v)
{
cin >> x >> y;
x--, y--;
}
sort(v.begin(), v.end());
int64_t encounters = 0;
for (auto [x, y] : v)
{
encounters += st.get(0, y+1, -2*m+1, d-x-y+1);
st.update(y, -x-y, 1);
}
st.clear();
for (auto [x, y] : v)
{
encounters += st.get(y+1, m, -2*m+1, d-x+y+1);
st.update(y, y-x, 1);
}
st.clear();
for (int i = v.size()-1; i >= 0; i--)
{
auto [x, y] = v[i];
encounters += st.get(0, y+1, -2*m+1, d+x-y+1);
st.update(y, x-y, 1);
}
st.clear();
for (int i = v.size()-1; i >= 0; i--)
{
auto [x, y] = v[i];
encounters += st.get(y+1, m, -2*m+1, d+x+y+1);
st.update(y, x+y, 1);
}
cout << (encounters / 2) << "\n";
}
struct BIT3D
{
int a, b, c;
vector<vector<vector<int>>> data;
BIT3D(int a, int b, int c) : a(a), b(b), c(c), data(a+1, vector<vector<int>>(b+1, vector<int>(c+1))) {}
void update(int x, int _y, int _z, int val)
{
for (++x;x<=a;x+=x&(-x))
for (int y=_y+1;y<=b;y+=y&(-y))
for (int z=_z+1;z<=c;z+=z&(-z))
data[x][y][z] += val;
}
int get(int x, int _y, int _z)
{
int res = 0;
for (;x;x-=x&(-x))
for (int y=_y;y;y-=y&(-y))
for (int z=_z;z;z-=z&(-z))
res += data[x][y][z];
return res;
}
int query(int xl, int xr, int yl, int yr, int zl, int zr)
{
int a3 = get(xr, yr, zr);
int a2 = get(xl, yr, zr);
int b2 = get(xr, yl, zr);
int c2 = get(xr, yr, zl);
int a1 = get(xr, yl, zl);
int b1 = get(xl, yr, zl);
int c1 = get(xl, yl, zr);
int a0 = get(xl, yl, zl);
return a3 - a2 - b2 - c2 + a1 + b1 + c1 - a0;
}
void reset()
{
for (int x = 1; x <= a; x++)
for (int y = 1; y <= b; y++)
for (int z = 1; z <= c; z++)
data[x][y][z] = 0;
}
};
int64_t add_result(int a, int b, int c, const vector<array<int, 3>>& v, BIT3D& bit, int m, int d)
{
bit.reset();
array<int, 3> pad = {a, b, c};
int64_t res = 0;
int bonus = 0;
for (int i : pad)
if (i < 0)
bonus += m;
for (auto [x, y, z] : v)
{
int y_start = 0, y_end = y;
if (b == 1)
y_start = y, y_end = m;
int z_start = 0, z_end = z;
if (c == 1)
z_start = z, z_end = m;
int addition = a * x + y * b + c * z;
res += bit.query(y_start, y_end, z_start, z_end, 0, min(d + addition + 1 + bonus, 3*m));
bit.update(y, z, addition + bonus, 1);
}
return res;
}
int64_t __find(int a, const vector<array<int, 3>>& v, BIT3D& bit, int m, int d)
{
int64_t res = 0;
for (int b = -1; b <= 1; b+=2)
for (int c = -1; c <= 1; c+=2)
res += add_result(a, b, c, v, bit, m, d);
return res;
}
void solve3d()
{
int n, d, m;
cin >> n >> d >> m;
BIT3D bit(m, m, 3*m);
vector<array<int, 3>> v(n);
for (auto& [x, y, z] : v)
{
cin >> x >> y >> z;
x--, y--, z--;
}
sort(v.begin(), v.end());
int64_t res = __find(-1, v, bit, m, d);
reverse(v.begin(), v.end());
res += __find(1, v, bit, m, d);
cout << (res / 2) << "\n";
}
int32_t main()
{
int b;
cin >> b;
if (b == 1)
solve1d();
else if (b == 2)
solve2d();
else
solve3d();
}
Compilation message
pairs.cpp: In member function 'void SegTree1d::update(int, int, int, int, int)':
pairs.cpp:38:26: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
38 | int m = l+r>>1;
| ~^~
pairs.cpp: In member function 'int SegTree1d::get(int, int, int, int, int)':
pairs.cpp:49:26: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
49 | int m = l+r>>1;
| ~^~
pairs.cpp: In constructor 'SegTree2d::SegTree2d(int, int, int, int)':
pairs.cpp:86:27: warning: 'SegTree2d::up' will be initialized after [-Wreorder]
86 | vector<int> down, up;
| ^~
pairs.cpp:86:21: warning: 'std::vector<int> SegTree2d::down' [-Wreorder]
86 | vector<int> down, up;
| ^~~~
pairs.cpp:87:9: warning: when initialized here [-Wreorder]
87 | SegTree2d (int ll, int rr, int dd, int uu) : ll(ll), rr(rr), uu(uu), dd(dd), root(1, -1), up(1, -1), down(1, -1) {}
| ^~~~~~~~~
pairs.cpp: In member function 'void SegTree2d::update_row(int, int, int, int, int)':
pairs.cpp:113:26: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
113 | int m = l+r>>1;
| ~^~
pairs.cpp: In member function 'void SegTree2d::update_grid(int, int, int, int, int, int)':
pairs.cpp:153:26: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
153 | int m = d+u>>1;
| ~^~
pairs.cpp: In member function 'int SegTree2d::get_row(int, int, int, int, int) const':
pairs.cpp:181:26: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
181 | int m = l+r>>1;
| ~^~
pairs.cpp: In member function 'int SegTree2d::get_grid(int, int, int, int, int, int, int) const':
pairs.cpp:192:26: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
192 | int m = d+u>>1;
| ~^~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
212 KB |
Output is correct |
2 |
Correct |
0 ms |
212 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
724 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
39 ms |
724 KB |
Output is correct |
2 |
Correct |
29 ms |
724 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
195 ms |
23280 KB |
Output is correct |
2 |
Correct |
107 ms |
23276 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
197 ms |
23276 KB |
Output is correct |
2 |
Correct |
86 ms |
4916 KB |
Output is correct |
3 |
Correct |
70 ms |
1368 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
31 ms |
11964 KB |
Output is correct |
2 |
Correct |
28 ms |
12060 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
343 ms |
2612 KB |
Output is correct |
2 |
Correct |
301 ms |
2648 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1220 ms |
67016 KB |
Output is correct |
2 |
Correct |
1180 ms |
67064 KB |
Output is correct |
3 |
Correct |
857 ms |
34072 KB |
Output is correct |
4 |
Correct |
1096 ms |
49752 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
3479 ms |
524288 KB |
Execution killed with signal 9 |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
9 ms |
5668 KB |
Output is correct |
2 |
Correct |
13 ms |
5588 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
84 ms |
1984 KB |
Output is correct |
2 |
Incorrect |
84 ms |
2104 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
216 ms |
5040 KB |
Output is correct |
2 |
Correct |
208 ms |
5068 KB |
Output is correct |
3 |
Correct |
206 ms |
5028 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
264 ms |
7588 KB |
Output is correct |
2 |
Correct |
252 ms |
7592 KB |
Output is correct |
3 |
Correct |
233 ms |
7584 KB |
Output is correct |