답안 #259981

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
259981 2020-08-08T21:30:42 Z thecodingwizard Pairs (IOI07_pairs) C++11
100 / 100
1890 ms 9852 KB
#include <bits/stdc++.h>

using namespace std;

#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template <class T> using Tree = tree<T, null_type, less<T>,
     rb_tree_tag, tree_order_statistics_node_update>;
#define ii pair<int, int>
#define f first
#define s second

int b, n, d, m; 

struct FT {
    vector<int> ft;
    int n;
    void init(int _n) {
        n = _n;
        ft.assign(n+1, 0);
    }
    void upd(int k, int v) {
        while (k <= n) {
            ft[k] += v;
            k += k&-k;
        }
    }
    int qry(int k) {
        k = min(k, n-1);
        if (k <= 0) return 0;
        int sum = 0;
        while (k) {
            sum += ft[k];
            k -= k&-k;
        }
        return sum;
    }
};

struct FT2D {
    vector<FT> ft;
    int X, Y;
    void init(int _x, int _y) {
        X = _x; Y = _y;
        ft.resize(X+1);
        for (int i = 0; i <= X; i++) {
            ft[i].init(Y+1);
        }
    }
    void upd(int x, int y, int v) {
        assert(x > 0 && x <= X && y > 0 && y <= Y);
        while (x < X) {
            ft[x].upd(y, v);
            x += x&-x;
        }
    }
    int qry(int x, int y) {
        if (x <= 0 || y <= 0) return 0;
        x = min(x, X); y = min(y, Y);
        int sum = 0;
        while (x) {
            sum += ft[x].qry(y);
            x -= x & -x;
        }
        return sum;
    }
};

int main() {
    cin.tie(0); ios_base::sync_with_stdio(false);
    cin >> b >> n >> d >> m;
    if (b == 1) {
        Tree<pair<int, int>> TS;
        long long ans = 0;
        vector<int> nums;
        for (int i = 0; i < n; i++) {
            int x; cin >> x;
            nums.push_back(x);
        }
        sort(nums.begin(), nums.end());
        int ct = 0;
        for (int x : nums) {
            ans += ct-TS.order_of_key(make_pair(x-d, 0));
            TS.insert(make_pair(x, ct++));
        }
        cout << ans << endl;
    } else if (b == 2) {
        vector<ii> nums;
        for (int i = 0; i < n; i++) {
            int x, y; cin >> x >> y;
            nums.push_back(make_pair(x-y, x+y));
        }
        sort(nums.begin(), nums.end());
        int l = 0;
        FT ft; ft.init(2*m+1);
        long long ans = 0;
        for (int r = 0; r < n; r++) {
            while (nums[r].f - nums[l].f > d) {
                ft.upd(nums[l].s, -1);
                l++;
            }
            ans += ft.qry(nums[r].s+d) - ft.qry(nums[r].s-d-1);
            ft.upd(nums[r].s, 1);
        }
        cout << ans << endl;
    } else {
        vector<ii> nums[m+1];
        for (int i = 0; i < n; i++) {
            int x, y, z; cin >> x >> y >> z;
            nums[z].push_back(make_pair(x-y+m, x+y));
        }
        FT2D ft[m+1];
        for (int i = 1; i <= m; i++) {
            ft[i].init(2*m+1, 2*m+1);
            for (ii j : nums[i]) {
                ft[i].upd(j.f, j.s, 1);
            }
        }
        long long ans = 0;
        for (int i = 1; i <= m; i++) {
            for (ii j : nums[i]) {
                for (int k = 1; k <= m; k++) {
                    int d2 = d - abs(k - i);
                    if (d2 < 0) continue;
                    ans += ft[k].qry(j.f + d2, j.s + d2) - ft[k].qry(j.f + d2, j.s - d2 - 1) - ft[k].qry(j.f - d2 - 1, j.s + d2) + ft[k].qry(j.f - d2 - 1, j.s - d2 - 1);
                }
                ans--; // don't count the point itself
            }
        }
        assert(ans % 2 == 0);
        cout << ans / 2 << endl;
    }
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 384 KB Output is correct
2 Correct 0 ms 384 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 384 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 99 ms 7412 KB Output is correct
2 Correct 93 ms 7344 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 107 ms 7828 KB Output is correct
2 Correct 101 ms 7932 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 119 ms 7796 KB Output is correct
2 Correct 104 ms 7796 KB Output is correct
3 Correct 104 ms 7924 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 896 KB Output is correct
2 Correct 1 ms 1024 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 34 ms 2044 KB Output is correct
2 Correct 31 ms 2044 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 41 ms 2300 KB Output is correct
2 Correct 35 ms 2300 KB Output is correct
3 Correct 41 ms 2300 KB Output is correct
4 Correct 37 ms 2172 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 49 ms 2928 KB Output is correct
2 Correct 44 ms 2936 KB Output is correct
3 Correct 43 ms 3056 KB Output is correct
4 Correct 43 ms 2928 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 7680 KB Output is correct
2 Correct 11 ms 7680 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 41 ms 2144 KB Output is correct
2 Correct 75 ms 2136 KB Output is correct
3 Correct 44 ms 2136 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 291 ms 6136 KB Output is correct
2 Correct 934 ms 6136 KB Output is correct
3 Correct 376 ms 6100 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 953 ms 9852 KB Output is correct
2 Correct 1890 ms 9720 KB Output is correct
3 Correct 466 ms 9848 KB Output is correct