Submission #9694915


Source Code Expand

#include <algorithm>
#include <bits/stdc++.h>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define rep(X, S, E) for (int(X) = (S); (X) < (E); ++(X))
#define rrep(X, S, E) for (int(X) = (E)-1; (X) >= (S); --(X))
#define arep(X, Y) for (auto(X) : Y)
#define all(X) (X).begin(), (X).end()
#define pb push_back
#define mp make_pair
#define fi first
#define sc second
#define print(x) cout << x << endl
#define printDouble(x) cout << fixed << setprecision(13) << x << endl
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;

using decendingQueue = priority_queue<ll, vl>;              //降順
using ascendingQueue = priority_queue<ll, vl, greater<ll>>; //昇順

const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const ll INT_INF = 1e9;
const ll LL_INF = 1e18;
const int mod = 1000000007;

template <class T> void mySort(vector<T> &X, bool isAscending) {
  // 昇順
  if (isAscending) {
    sort(all(X));
  } else {
    // 降順
    sort(all(X), greater<T>());
  }
}

long long gcd(long long m, long long n) {
  if (m < n)
    return gcd(n, m);
  if (n == 0)
    return m;
  return gcd(n, m % n);
}

long long lcm(long long m, long long n) {
  // m * nでlong型のオーバフローを発生させないため、先に割り算から行う
  return m * (n / gcd(m, n));
}

// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
struct mint {
  ll x; // typedef long long ll;
  mint(ll x = 0) : x((x % mod + mod) % mod) {}
  mint &operator+=(const mint a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res *= a;
  }
  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint &operator/=(const mint a) { return (*this) *= a.inv(); }
  mint operator/(const mint a) const {
    mint res(*this);
    return res /= a;
  }
};

// combination mod prime
// https://www.youtube.com/watch?v=8uowVvQ_-Mo&feature=youtu.be&t=1619
struct combination {
  vector<mint> fact, ifact;
  combination(int n) : fact(n + 1), ifact(n + 1) {
    assert(n < mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i)
      fact[i] = fact[i - 1] * i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i)
      ifact[i - 1] = ifact[i] * i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n)
      return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
};

vector<long long> SieveOfEratosthenes(int max) {
  vector<long long> sieve;
  vector<long long> primes;

  for (int i = 1; i < max + 1; ++i) {
    sieve.push_back(i);
  }

  sieve[0] = 0;
  for (int i = 2; i < max + 1; ++i) {
    if (sieve[i - 1] != 0) {
      primes.push_back(sieve[i - 1]);
      for (int j = 2 * sieve[i - 1]; j < max + 1; j += sieve[i - 1]) {
        sieve[j - 1] = 0;
      }
    }
  }
  return primes;
}

class UnionFindTree {
private:
  vector<int> par;
  vector<int> rnk;
  vector<int> siz;

public:
  UnionFindTree(int n) {
    par.assign(n, -1);
    rnk.assign(n, -1);
    siz.assign(n, -1);

    for (int i = 0; i < n; ++i) {
      par[i] = i;
      rnk[i] = 0;
      siz[i] = 1;
    }
  }

  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }

  bool same(int x, int y) { return find(x) == find(y); }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rnk[x] < rnk[y]) {
      par[x] = y;
      siz[y] += siz[x];
    } else {
      par[y] = x;
      siz[x] += siz[y];
      if (rnk[x] == rnk[y])
        ++rnk[x];
    }
  }

  int size(int x) {
    x = find(x);
    return siz[x];
  }
};

class Edge {
public:
  ll from;
  ll to;
  ll cost;

  Edge() {}
  Edge(ll from, ll to, ll cost) {
    this->from = from;
    this->to = to;
    this->cost = cost;
  }

  bool operator<(const Edge &edge) const {
    return cost < edge.cost; //昇順
  }
};

class Graph {
public:
  ll nodes; // ノード数
  vector<Edge> edges;

  Graph() {}
  Graph(ll nodes) { this->nodes = nodes; }
  void addEdge(ll from, ll to, ll cost) {
    this->edges.push_back(Edge(from, to, cost));
  }
};

// クラスカル法
// 連結グラフの最小全域木を求める
class Kruskal {
private:
  Graph graph;
  vector<Edge> MinimumSpanningTree;
  ll minimumCost;
  void searchMinimumSpanningTree() {
    UnionFindTree uf(graph.nodes);
    sort(all(graph.edges));
    for (auto edge : graph.edges) {
      if (!uf.same(edge.from, edge.to)) {
        uf.unite(edge.from, edge.to);
        MinimumSpanningTree.push_back(edge);
      }
    }
  }

public:
  Kruskal(Graph graph) { this->graph = graph; }
  ll getMinimumSpanningTreeCost() {
    searchMinimumSpanningTree();
    ll cost = 0;
    for (auto tr : MinimumSpanningTree) {
      cost += tr.cost;
    }
    return cost;
  }
};

// ダイクストラ法 O((E+V)logV)
// 最小経路問題を解くためのアルゴリズム。辺の重みに負数を含む場合は利用不可
// 無向グラフの場合はコメントアウト箇所をコメントイン
class Dijkstra {
private:
  Graph graph;
  map<ll, vector<Edge>> fromPaths;
  vl distances;
  vl srcs;

public:
  Dijkstra(Graph graph) {
    this->graph = graph;
    for (auto edge : graph.edges) {
      fromPaths[edge.from].push_back(edge);
      // fromPaths[edge->to].push_back(Edge(edge->to, edge->from, edge->cost));
    }
  }
  void searchMinimumPathFrom(ll src) {
    // 複数回呼ばれる度に計算する
    distances = vl(graph.nodes + 1, LL_INF);
    srcs = vl(graph.nodes + 1, LL_INF);

    // 距離が近い順番に捜査していく
    priority_queue<pll, vector<pll>, greater<pll>> pq;
    distances[src] = 0;
    srcs[src] = -1;

    pq.push(mp(0ll, src));
    while (!pq.empty()) {
      int u = pq.top().second;
      double uw = pq.top().first;
      pq.pop();

      if (distances[u] < uw) {
        continue;
      };

      for (auto edge : fromPaths[u]) {
        int v = edge.to;
        ll w = edge.cost;
        if (distances[v] > distances[u] + w) {
          distances[v] = distances[u] + w;
          srcs[v] = u;
          pq.push(mp(distances[v], v));
        }
      }
    }
  };
  ll getDistance(ll n) { return distances[n]; }
  ll getFrom(ll n) { return srcs[n]; }
};

// ベルマンフォード O(|V||E|)
// 負コストが含まれていても最短経路問題を解くためのアルゴリズム。閉路の検出も可能
// 有向グラフ
class BellmanFord {
private:
  Graph graph;
  // 閉路が含まれるかは個々のノードごとに管理する必要あり
  vector<bool> hasNegativeCycles;
  vector<ll> distances;
  vl srcs;

public:
  BellmanFord(Graph graph) {
    ll nodes = graph.nodes + 1;

    this->graph = graph;
    distances = vector<ll>(nodes, LL_INF);
    hasNegativeCycles = vector<bool>(nodes, false);
  }
  void searchMinimumPathFrom(ll src) {
    distances[src] = 0;

    for (ll i = 0; i < graph.nodes - 1; i++) {
      for (auto edge : graph.edges) {
        ll u = edge.from;
        ll v = edge.to;
        ll w = edge.cost;
        if (distances[u] != LL_INF) {
          chmin(distances[v], distances[u] + w);
        }
      }
    }

    for (auto edge : graph.edges) {
      ll u = edge.from;
      ll v = edge.to;
      ll w = edge.cost;
      if (distances[u] == LL_INF) {
        continue;
      }
      if (distances[u] + w < distances[v]) {
        hasNegativeCycles[v] = true;
      }
    }

    for (ll i = 0; i < graph.nodes; i++) {
      for (auto edge : graph.edges) {
        ll u = edge.from;
        ll v = edge.to;
        ll w = edge.cost;
        if (distances[u] == LL_INF) {
          continue;
        }
        chmin(distances[v], distances[u] + w);
        if (hasNegativeCycles[u] == true) {
          hasNegativeCycles[v] = true;
        }
      }
    }
  }
  ll getDistance(ll n) { return distances[n]; }
  bool hasNegativeCycle(ll n) { return hasNegativeCycles[n]; }
  ll getFrom(ll n) { return srcs[n]; }
};

// O(V^3) 有向グラフ
class WarshallFloyd {
private:
  Graph graph;
  int nodes = this->graph.nodes + 1;
  vector<vector<ll>> distances;

public:
  WarshallFloyd(Graph graph) {
    this->graph = graph;
    nodes = this->graph.nodes + 1;
    this->distances = vector<vector<ll>>(nodes, vector<ll>(nodes, LL_INF));
    for (auto edge : graph.edges) {
      int from = edge.from;
      int to = edge.to;
      int cost = edge.cost;
      distances[from][to] = cost;
    }
  }
  void searchMinimumPath() {
    for (int k = 0; k < nodes; k++) {
      for (int i = 0; i < nodes; i++) {
        for (int j = 0; j < nodes; j++) {
          if (distances[i][k] == LL_INF || distances[k][j] == LL_INF) {
            continue;
          }
          if (distances[i][k] + distances[k][j] < distances[i][j]) {
            distances[i][j] = distances[i][k] + distances[k][j];
          }
        }
      }
    }
  }
  ll getDistance(int from, int to) { return distances[from][to]; }
};

void solve(long long N, long long D, std::vector<long long> X) {
  ll cnt1 = 0; // X[j] - X[i] <= D && X[k] - X[j] <= D
  rep(j, 1, N - 1) {
    int idx1 = lower_bound(all(X), X[j] - D) - X.begin();
    int idx2 = upper_bound(all(X), X[j] + D) - X.begin() - 1;
    cnt1 += (j - idx1) * (idx2 - j);
  }

  ll cnt2 = 0; // X[k] - X[i] <= D
  rep(i, 0, N - 2) {
    int idx = upper_bound(all(X), X[i] + D) - X.begin() - 1;
    int num = idx - i;

    if (num < 2) {
      continue;
    }

    cnt2 += (ll)num * (num - 1) / 2;
  }

  print(cnt1 - cnt2);
}

int main() {
  long long N;
  scanf("%lld", &N);
  long long D;
  scanf("%lld", &D);
  std::vector<long long> X(N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &X[i]);
  }
  solve(N, D, std::move(X));
  return 0;
}

Submission Info

Submission Time
Task C - 徒歩圏内
User righttoleft1134
Language C++14 (GCC 5.4.1)
Score 0
Code Size 10633 Byte
Status WA
Exec Time 27 ms
Memory 1024 KB

Compile Error

./Main.cpp: In function ‘int main()’:
./Main.cpp:451:20: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
   scanf("%lld", &N);
                    ^
./Main.cpp:453:20: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
   scanf("%lld", &D);
                    ^
./Main.cpp:456:25: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
     scanf("%lld", &X[i]);
                         ^

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 0 / 400
Status
AC × 4
AC × 14
WA × 2
Set Name Test Cases
Sample sample-01.txt, sample-02.txt, sample-03.txt, sample-04.txt
All 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, sample-01.txt, sample-02.txt, sample-03.txt, sample-04.txt
Case Name Status Exec Time Memory
01.txt AC 25 ms 1024 KB
02.txt AC 27 ms 1024 KB
03.txt WA 20 ms 1024 KB
04.txt AC 25 ms 1024 KB
05.txt AC 26 ms 1024 KB
06.txt WA 22 ms 1024 KB
07.txt AC 23 ms 1024 KB
08.txt AC 22 ms 896 KB
09.txt AC 1 ms 256 KB
10.txt AC 22 ms 1024 KB
11.txt AC 26 ms 1024 KB
12.txt AC 21 ms 1024 KB
sample-01.txt AC 1 ms 256 KB
sample-02.txt AC 1 ms 256 KB
sample-03.txt AC 1 ms 256 KB
sample-04.txt AC 1 ms 256 KB