Problem:
Problem F : Dungeon (I)
あなたはとあるゲームの開発に携わっている。
そのゲームはランダムに生成されたダンジョンをプレイヤーが探索するというものである。
このゲームで生成されるダンジョンには
n
個の部屋が存在しており、0から
n-1
までの番号が割り振られている。
部屋と部屋は通路で結ばれている。部屋と部屋を結ぶ通路は、
m
本ある。
通路はどちらの方向へも進むことができる。
また、部屋と部屋の間には距離が設定されている。
生成されたダンジョンではいくつかの通路を経由して、ある部屋から他のすべての部屋へ行くことが可能である。
そして、プレイヤーがゲームを行う際に、0番の部屋がスタート地点、
n-1
番の部屋がゴール地点として選ばれる。
ユーザーがダンジョンを探索する際に、手助けになるようなアイテムが入った宝箱を、どこかの部屋に設置したい。
その時に、スタート地点から遠すぎたり、ゴール地点から近すぎると意味がない。
そこで、スタートから距離
fs
以内で辿りつけて、ゴールに辿り着くために最短経路を通った場合に、少なくとも
fg
かかる部屋を宝箱を設置する候補としたい。
生成されたダンジョンと、
q
が与えられる。
q
個のクエリーについて、宝箱を設置する場所の候補の数を数えて欲しい。
Input
入力は以下のフォーマットで与えられる。
n
m
a
1
b
1
c
1
.
.
.
a
m
b
m
c
m
q
fs
1
fg
1
.
.
.
fs
q
fg
q
a
i
b
i
c
i
は 部屋
a
i
と
b
i
を結ぶ通路の距離が
c
i
であることを表す。
入力は以下の制約を満たす
2  ≤
n
≤ 100,000
0 ≤
a
i
,
b
i
<
n
0 ≤
c
i
≤ 100,000
n-1
≤
m
≤ 100,000
1 ≤
q
≤ 100,000
0 ≤
fs
i
,
fg
i
≤ 2
60
Output
各クエリーについて、答えの値を1行に出力せよ
Sample Input 1
4 4
0 1 3
1 3 4
0 2 2
2 3 1
4
0 0 
2 2
2 1
3 4
Sample Output 1
1
1
2
1

Submitted solutions:

code_snippet: #include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<ll,int> P;
#define pu push
#define pb push_back
#define mp make_pair
#define INF 10000000000000000
int n,m;
ll start[100005];
ll goal[100005];
ll d[100005];
pair<ll,ll> qwe[100005];
struct edge{
    int to; ll cost;
    edge(int a,int b):to(a),cost(b){}
};
vector<edge>vec[100005];
void dijkstra(int s){
    priority_queue<P,vector<P>,greater<P> > que;
    que.pu(mp(0,s));
    fill(d,d+n,INF);
    d[s]=0;
    while(!que.empty()){
        P p=que.top(); que.pop();
        int V=p.second;
        if(d[V]<p.first) continue;
        for(int i=0;i<vec[V].size();i++){
            edge e=vec[V][i];
            if(d[e.to] > d[V]+e.cost){
                d[e.to]=d[V]+e.cost;
                que.push(mp(d[e.to],e.to));
            }
        }
    }
}
vector<ll>seg[1<<18];
ll limits,limite;
void update1(vector<ll> x,int a){
    seg[a+(1<<17)-1]=x;
}
void update(){
    for(int i=(1<<17)-2;i>=0;i--){
        seg[i].resize(seg[i*2+1].size()+seg[i*2+2].size());
        merge(seg[i*2+1].begin(),seg[i*2+1].end(),seg[i*2+2].begin(),seg[i*2+2].end(),seg[i].begin());
    }
}
int sum(int a,int b,int k,int l,int r){
    if(l>b || a>r){
        return 0;
    }else if(a<=l && r<=b){
        int rp=lower_bound(seg[k].begin(),seg[k].end(),limite)-seg[k].begin();
        return seg[k].size()-rp;
    }else{
        return sum(a,b,k*2+1,l,(l+r)/2)+sum(a,b,k*2+2,(l+r)/2+1,r);
    }
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        ll c;
        scanf("%d %d %lld",&a,&b,&c);
        vec[a].pb(edge(b,c)); vec[b].pb(edge(a,c));
    }
    dijkstra(0);
    for(int i=0;i<n;i++){
        start[i]=d[i];
    }
    dijkstra(n-1);
    for(int i=0;i<n;i++){
        goal[i]=d[i];
        qwe[i]=mp(start[i],goal[i]);
    }
    sort(qwe,qwe+n);
    for(int i=0;i<n;i++){
        vector<ll>er; er.pb(qwe[i].second);
        update1(er,i); start[i]=qwe[i].first;
    }
    update();
    int Q;
    scanf("%d",&Q);
    for(int i=0;i<Q;i++){
        scanf("%lld %lld",&limits,&limite);
        int eo=upper_bound(start,start+n,limits)-start;
        printf("%d\n",sum(0,eo-1,0,0,(1<<17)-1));
    }
}
accuracy: 1
time_ms: 180
memory_kb: 37832
final_rank: 6

code_snippet: #include <algorithm>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

typedef struct {
  int id;
  long long cost;
} node;

vector<long long> hoge(vector<vector<node>> &nodes, int n, int s) {
  vector<long long> cost(n, 1e15);
  auto compare = [](node &a, node &b) { return a.cost > b.cost; };
  priority_queue<node, vector<node>, decltype(compare)> queue{compare};
  vector<int> status(n, 0);

  cost[s] = 0;
  queue.push({s, 0});

  while (!queue.empty()) {
    int cur = queue.top().id;
    queue.pop();

    for (auto &nextnode : nodes[cur]) {
      long long cost_new = cost[cur] + nextnode.cost;
      if (cost[nextnode.id] <= cost_new)
        continue;
      cost[nextnode.id] = cost_new;
      queue.push({nextnode.id, cost[nextnode.id]});
    }
  }

  return cost;
}

struct res {
  int id;
  long long a;
  long long b;
};

int main() {
  int n, m;
  cin >> n >> m;

  int size = 1000;
  vector<vector<node>> nodes(n);
  for (int i = 0; i < m; ++i) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    nodes[a].push_back({b, c});
    nodes[b].push_back({a, c});
  }

  vector<long long> v1 = hoge(nodes, n, 0);
  vector<long long> v2 = hoge(nodes, n, n - 1);

  vector<res> v3(n);
  for (int i = 0; i < n; ++i)
    v3[i] = {i, v1[i], v2[i]};

  sort(v3.begin(), v3.end(), [](res &a, res &b) { return (a.a != a.b) ? a.a < b.a : b.b < a.b; });

  int q, fs, fg;
  cin >> q;
  while (scanf("%d %d", &fs, &fg) != EOF) {
    int cnt = 0;
    for (auto &v : v3) {
      if (fs < v.a)
        break;
      if (fg <= v.b)
        ++cnt;
      else
        continue;
    }
    printf("%d\n", cnt);
  }
}
accuracy: 0.28888888888888886
time_ms: 30
memory_kb: 12040
final_rank: 18

code_snippet: #include <algorithm>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

typedef struct {
  int id;
  long long cost;
} node;

vector<long long> hoge(vector<vector<node>> &nodes, int n, int s) {
  vector<long long> cost(n, 1e15);
  auto compare = [](node &a, node &b) { return a.cost > b.cost; };
  priority_queue<node, vector<node>, decltype(compare)> queue{compare};
  vector<int> status(n, 0);

  cost[s] = 0;
  queue.push({s, 0});

  while (!queue.empty()) {
    int cur = queue.top().id;
    queue.pop();

    for (auto &nextnode : nodes[cur]) {
      long long cost_new = cost[cur] + nextnode.cost;
      if (cost[nextnode.id] <= cost_new)
        continue;
      cost[nextnode.id] = cost_new;
      queue.push({nextnode.id, cost[nextnode.id]});
    }
  }

  return cost;
}

struct res {
  int id;
  long long a;
  long long b;
};

int main() {
  int n, m;
  cin >> n >> m;

  int size = 1000;
  vector<vector<node>> nodes(n);
  for (int i = 0; i < m; ++i) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    nodes[a].push_back({b, c});
    nodes[b].push_back({a, c});
  }

  vector<long long> v1 = hoge(nodes, n, 0);
  vector<long long> v2 = hoge(nodes, n, n - 1);

  vector<res> v3(n);
  for (int i = 0; i < n; ++i)
    v3[i] = {i, v1[i], v2[i]};

  sort(v3.begin(), v3.end(), [](res &a, res &b) { return (a.a != a.b) ? a.a < b.a : b.b < a.b; });

  int q, fs, fg;
  cin >> q;
  while (scanf("%d %d", &fs, &fg) != EOF) {
    int cnt = 0;
    for (auto &v : v3) {
      if (fs < v.a)
        break;
      if (v.b < fg)
        continue;
      ++cnt;
    }
    printf("%d\n", cnt);
  }
}
accuracy: 0.28888888888888886
time_ms: 30
memory_kb: 12052
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <vector>

using namespace std;

vector<int> hoge(vector<vector<int>> &matx, vector<vector<int>> &nodes, int s) {
  int n = matx.size();
  vector<int> cost(n, 1e7);
  priority_queue<int> queue;
  int cur = s;
  vector<int> status(n, 0);

  cost[cur] = 0;
  queue.push(cur);

  while (!queue.empty()) {
    cur = queue.top();
    queue.pop();

    for (auto &next : nodes[cur]) {
      int cost_new = cost[cur] + matx[cur][next];
      if (cost[next] <= cost_new)
        continue;
      cost[next] = cost_new;
      queue.push(next);
    }
  }

  return cost;
}

int main() {
  int n, m;
  cin >> n >> m;

  int size = 1000;
  vector<vector<int>> matx(n, vector<int>(n, 1e7));
  vector<vector<int>> nodes(n);
  for (int i = 0; i < m; ++i) {
    int a, b, c;
    cin >> a >> b >> c;
    matx[a][b] = matx[b][a] = c;
    nodes[a].push_back(b);
    nodes[b].push_back(a);
  }

  vector<int> v1 = hoge(matx, nodes, 0);
  vector<int> v2 = hoge(matx, nodes, n-1);

  int q, fs, fg;
  cin >> q;
  while (cin >> fs >> fg) {
    int cnt = 0;
    for (int i = 0; i < n; ++i)
      if (v1[i] <= fs && fg <= v2[i])
        ++cnt;
    cout << cnt << endl;
  }
}
accuracy: 0.8222222222222222
time_ms: 200
memory_kb: 9348
final_rank: 17

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <vector>

using namespace std;

vector<int> hoge(vector<vector<int>> &matx, vector<vector<int>> &nodes, int s) {
  int n = matx.size();
  vector<int> cost(n, 1e7);
  priority_queue<int> queue;
  int cur = s;
  vector<int> status(n, 0);

  cost[cur] = 0;
  queue.push(cur);

  while (!queue.empty()) {
    cur = queue.top();
    queue.pop();
    if (status[cur] == 1)
      continue;
    status[cur] = 1;

    for (auto &next : nodes[cur]) {
      int cost_new = cost[cur] + matx[cur][next];
      if (cost[next] <= cost_new)
        continue;
      cost[next] = cost_new;
      queue.push(next);
    }
  }

  return cost;
}

int main() {
  int n, m;
  cin >> n >> m;

  int size = 1000;
  vector<vector<int>> matx(n, vector<int>(n, 1e7));
  vector<vector<int>> nodes(n);
  for (int i = 0; i < m; ++i) {
    int a, b, c;
    cin >> a >> b >> c;
    matx[a][b] = matx[b][a] = c;
    nodes[a].push_back(b);
    nodes[b].push_back(a);
  }

  int q, fs, fg;
  cin >> q;
  while (cin >> fs >> fg) {
    int cnt = 0;
    vector<int> v1 = hoge(matx, nodes, 0);
    vector<int> v2 = hoge(matx, nodes, n-1);
    for (int i = 0; i < n; ++i)
      if (v1[i] <= fs && fg <= v2[i])
        ++cnt;
    cout << cnt << endl;
  }
}
accuracy: 0.06666666666666667
time_ms: 100
memory_kb: 4620
final_rank: 20

code_snippet: #include <iostream>
#include <vector>
#include <utility>
#include <queue>
#include <algorithm>
#include <unordered_map>

using namespace std;

int main() {
  int64_t n, m;
  int64_t a, b, c;
  int64_t q;
  int64_t fs, fg;
  int64_t inf = 10000000000000;
  int64_t chunk_size = 512;
  cin >> n >> m;
  vector<unordered_map<int64_t, int64_t>> edges(n);
  for (int i = 0; i < m; ++i) {
    cin >> a >> b >> c;
    if (edges[a].find(b) != edges[a].end()) {
      if (c < edges[a][b]) {
        edges[a].erase(b);
        edges[b].erase(a);
      }
    }
    edges[a].emplace(b, c);
    edges[b].emplace(a, c);
  }
  vector<pair<int64_t, int64_t>> costs(n);
  for (int i = 0; i < n; ++i) {
    costs[i].first = inf;
    costs[i].second = -1;
  }
  priority_queue<pair<int64_t, int64_t>> pq;
  pq.emplace(0, 0);
  while (!pq.empty()) {
    int64_t cost = -pq.top().first;
    int64_t id = pq.top().second;
    pq.pop();
    if (costs[id].first != inf) {
      continue;
    }
    costs[id].first = cost;
    for (auto& edge : edges[id]) {
      if (costs[edge.first].first != inf) {
        continue;
      }
      pq.emplace(-(cost + edge.second), edge.first);
    }
  }
  pq.emplace(0, n - 1);
  while (!pq.empty()) {
    int64_t cost = -pq.top().first;
    int64_t id = pq.top().second;
    pq.pop();
    if (costs[id].second != -1) {
      continue;
    }
    costs[id].second = cost;
    for (auto& edge : edges[id]) {
      if (costs[edge.first].second != -1) {
        continue;
      }
      pq.emplace(-(cost + edge.second), edge.first);
    }
  }
  sort(costs.begin(), costs.end());
  vector<vector<int64_t>> chunked_cost;
  for (int i = 0; i < n; i += chunk_size) {
    vector<int64_t> chunk(chunk_size, -1);
    for (int j = i; j < min(i + chunk_size, n); ++j) {
      chunk[j - i] = costs[j].second;
    }
    sort(chunk.begin(), chunk.end());
    chunked_cost.push_back(chunk);
  }
  cin >> q;
  for (int i = 0; i < q; ++i) {
    cin >> fs >> fg;
    int cnt = 0;
    int nmin_fs = upper_bound(costs.begin(), costs.end(), pair<int64_t, int64_t> {fs, inf}) - costs.begin();
    for (int j = 0; j < nmin_fs / chunk_size; j++) {
      cnt += chunked_cost[j].end() - lower_bound(chunked_cost[j].begin(), chunked_cost[j].end(), fg);
    }
    for (int j = nmin_fs / chunk_size * chunk_size; j < nmin_fs; ++j) {
      if (costs[j].second >= fg) {
        ++cnt;
      }
    }
    cout << cnt << endl;
  }
}
accuracy: 1
time_ms: 570
memory_kb: 23692
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <utility>
#include <queue>
#include <algorithm>
#include <unordered_map>

using namespace std;

int main() {
  int n, m;
  long long a, b, c;
  int q;
  long long fs, fg;
  cin >> n >> m;
  vector<unordered_map<long long, long long>> dists(n);
  for (int i = 0; i < m; ++i) {
    cin >> a >> b >> c;
    dists[a].emplace(b, c);
    dists[b].emplace(a, c);
  }
  vector<pair<long long, long long>> costs(n);
  for (int i = 0; i < n; ++i) {
    costs[i].first = 10000000001ll;
    costs[i].second = -1;
  }
  auto comp = [](const pair<long long, int>& a, const pair<long long, int>& b) { return a.first > b.first; };
  priority_queue<pair<long long, int>, vector<pair<long long, int>>, decltype(comp)> pq(comp);
  pq.emplace(0, 0);
  while (!pq.empty()) {
    auto item = pq.top();
    pq.pop();
    if (costs[item.second].first != 10000000001ll) {
      continue;
    }
    costs[item.second].first = item.first;
    for (auto& edge : dists[item.second]) {
      pq.emplace(item.first + edge.second, edge.first);
    }
  }
  pq.emplace(0, n - 1);
  while (!pq.empty()) {
    auto item = pq.top();
    pq.pop();
    if (costs[item.second].second != -1) {
      continue;
    }
    costs[item.second].second = item.first;
    for (auto& edge : dists[item.second]) {
      pq.emplace(item.first + edge.second, edge.first);
    }
  }
  unordered_map<long long, int> db_map;
  vector<pair<long long, vector<long long>>> db;
  for (auto& cost : costs) {
    if (db_map.find(cost.first) == db_map.end()) {
      db_map.emplace(cost.first, db.size());
      db.emplace_back();
      db.back().first = cost.first;
    }
    db[db_map[cost.first]].second.emplace_back(cost.second);
  }
  sort(db.begin(), db.end(), [](const pair<long long, vector<long long>>& a, const pair<long long, vector<long long>>& b) { return a.first < b.first; });
  for (auto& db_child : db) {
    sort(db_child.second.begin(), db_child.second.end());
  }
  vector<int> results;
  cin >> q;
  for (int i = 0; i < q; ++i) {
    cin >> fs >> fg;
    auto fsit = upper_bound(db.begin(), db.end(), pair<long long, vector<long long>> {fs, {}}, [](const pair<long long, vector<long long>>& a, const pair<long long, vector<long long>>& b) { return a.first < b.first; });
    int cnt = 0;
    for (auto it = db.begin(); it != fsit; ++it) {
      auto fgit = lower_bound(it->second.begin(), it->second.end(), fg);
      cnt += it->second.end() - fgit;
    }
    results.emplace_back(cnt);
  }
  for (auto c : results) {
    cout << c << endl;
  }
  return 0;
}
accuracy: 0.8666666666666667
time_ms: 1220
memory_kb: 27976
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
#include <utility>
#include <queue>
#include <algorithm>
#include <unordered_map>

using namespace std;

int main() {
  int n, m, a, b, c;
  int q, fs, fg;
  cin >> n >> m;
  unordered_map<int, unordered_map<int, int>> dist;
  vector<pair<int, int>> fdist(n);
  for (int i = 0; i < n; ++i) {
    fdist[i].first = -1;
    fdist[i].second = -1;
  }
  for (int i = 0; i < m; ++i) {
    cin >> a >> b >> c;
    if (dist.find(a) == dist.end()) {
      dist.emplace(a, unordered_map<int, int>{});
    }
    dist[a].emplace(b, c);
    if (dist.find(b) == dist.end()) {
      dist.emplace(b, unordered_map<int, int>{});
    }
    dist[b].emplace(a, c);
  }
  auto comp = [](const pair<int, int> &l, const pair<int, int> &r) { return l.first > r.first; };
  priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(comp)> pq(comp);
  pq.emplace(0, 0);
  while (!pq.empty()) {
    pair<int, int> item = pq.top();
    pq.pop();
    if (fdist[item.second].first != -1) {
      continue;
    }
    fdist[item.second].first = item.first;
    for (auto x : dist[item.second]) {
      pq.emplace(item.first + x.second, x.first);
    }
  }
  pq.emplace(0, n - 1);
  while (!pq.empty()) {
    pair<int, int> item = pq.top();
    pq.pop();
    if (fdist[item.second].second != -1) {
      continue;
    }
    fdist[item.second].second = item.first;
    for (auto x : dist[item.second]) {
      pq.emplace(item.first + x.second, x.first);
    }
  }
  unordered_map<int, int> distmap_warp;
  vector<pair<int, vector<int>>> distmap;
  for (int i = 0; i < n; ++i) {
    if (distmap_warp.find(fdist[i].first) == distmap_warp.end()) {
      distmap_warp.emplace(fdist[i].first, distmap.size());
      distmap.emplace_back();
    }
    distmap[distmap_warp[fdist[i].first]].first = fdist[i].first;
    distmap[distmap_warp[fdist[i].first]].second.emplace_back(fdist[i].second);
  }
  sort(distmap.begin(), distmap.end(), [](const pair<int, vector<int>>& a, const pair<int, vector<int>>& b) { return a.first < b.first; });
  for (auto& item : distmap) {
    sort(item.second.begin(), item.second.end());
  }
  cin >> q;
  vector<int> results;
  for (int i = 0; i < q; ++i) {
    cin >> fs >> fg;
    int cnt = 0;
    auto fsit = upper_bound(distmap.begin(), distmap.end(), pair<int, vector<int>>{fs, {}}, [](const pair<int, vector<int>>& a, const pair<int, vector<int>>& b) { return a.first < b.first; });
    for (auto it = distmap.begin(); it != fsit; ++it) {
      auto fgit = lower_bound(it->second.begin(), it->second.end(), fg);
      cnt += it->second.end() - fgit;
    }
    results.emplace_back(cnt);
  }
  for (int result : results) {
    cout << result << endl;
  }
  return 0;
}
accuracy: 0.8666666666666667
time_ms: 1280
memory_kb: 23800
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <utility>
#include <queue>
#include <algorithm>
#include <unordered_map>

using namespace std;

int main() {
  int n, m, a, b, c;
  int q, fs, fg;
  cin >> n >> m;
  unordered_map<int, unordered_map<int, int>> dist;
  vector<pair<int, int>> fdist(n);
  for (int i = 0; i < n; ++i) {
    fdist[i].first = -1;
    fdist[i].second = -1;
  }
  for (int i = 0; i < m; ++i) {
    cin >> a >> b >> c;
    if (dist.find(a) == dist.end()) {
      dist.emplace(a, unordered_map<int, int>{});
    }
    dist[a].emplace(b, c);
    if (dist.find(b) == dist.end()) {
      dist.emplace(b, unordered_map<int, int>{});
    }
    dist[b].emplace(a, c);
  }
  auto comp = [](const pair<int, int> &l, const pair<int, int> &r) { return l.first > r.first; };
  priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(comp)> pq(comp);
  pq.emplace(0, 0);
  while (!pq.empty()) {
    pair<int, int> item = pq.top();
    pq.pop();
    if (fdist[item.second].first != -1) {
      continue;
    }
    fdist[item.second].first = item.first;
    for (auto x : dist[item.second]) {
      pq.emplace(item.first + x.second, x.first);
    }
  }
  pq.emplace(0, n - 1);
  while (!pq.empty()) {
    pair<int, int> item = pq.top();
    pq.pop();
    if (fdist[item.second].second != -1) {
      continue;
    }
    fdist[item.second].second = item.first;
    for (auto x : dist[item.second]) {
      pq.emplace(item.first + x.second, x.first);
    }
  }
  unordered_map<int, int> distmap_warp;
  vector<pair<int, vector<int>>> distmap;
  for (int i = 0; i < n; ++i) {
    if (distmap_warp.find(fdist[i].first) == distmap_warp.end()) {
      distmap_warp.emplace(fdist[i].first, distmap.size());
      distmap.emplace_back();
    }
    distmap[distmap_warp[fdist[i].first]].first = fdist[i].first;
    distmap[distmap_warp[fdist[i].first]].second.emplace_back(fdist[i].second);
  }
  sort(distmap.begin(), distmap.end(), [](const pair<int, vector<int>>& a, const pair<int, vector<int>>& b) { return a.first < b.first; });
  for (auto& item : distmap) {
    sort(item.second.begin(), item.second.end());
  }
  cin >> q;
  for (int i = 0; i < q; ++i) {
    cin >> fs >> fg;
    int cnt = 0;
    auto fsit = upper_bound(distmap.begin(), distmap.end(), pair<int, vector<int>>{fs, {}}, [](const pair<int, vector<int>>& a, const pair<int, vector<int>>& b) { return a.first < b.first; });
    for (auto it = distmap.begin(); it != fsit; ++it) {
      auto fgit = lower_bound(it->second.begin(), it->second.end(), fg);
      cnt += it->second.end() - fgit;
    }
    cout << cnt << endl;
  }
  return 0;
}
accuracy: 0.8666666666666667
time_ms: 1290
memory_kb: 23776
final_rank: 16

code_snippet: // includes
#include <bits/stdc++.h>

// macros
#define ll long long int
#define pb emplace_back
#define mk make_pair
#define pq priority_queue
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define rep(i, n) FOR(i, 0, n)
#define rrep(i, n) for(int i=((int)(n)-1);i>=0;i--)
#define irep(itr, st) for(auto itr = (st).begin(); itr != (st).end(); ++itr)
#define irrep(itr, st) for(auto itr = (st).rbegin(); itr != (st).rend(); ++itr)
#define vrep(v, i) for(int i = 0; i < (v).size(); i++)
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end())
#define FI first
#define SE second
#define dump(a, n) for(int i = 0; i < n; i++)cout << a[i] << "\n "[i + 1 != n];
#define dump2(a, n, m) for(int i = 0; i < n; i++)for(int j = 0; j < m; j++)cout << a[i][j] << "\n "[j + 1 != m];
#define bit(n) (1LL<<(n))
#define INT(n) int n; cin >> n;
#define LL(n) ll n; cin >> n;
#define DOUBLE(n) double n; cin >> n;
using namespace std;

//  types
typedef pair<int, int> P;
typedef pair<ll, int> Pl;
typedef pair<ll, ll> Pll;
typedef pair<double, double> Pd;
typedef complex<double> cd;
 
// constants
const int inf = 1e9;
const ll linf = 1LL << 50;
const double EPS = 1e-10;
const int mod = 1e9 + 7;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, -1, 0, 1};

// solve
template <class T>bool chmax(T &a, const T &b){if(a < b){a = b; return 1;} return 0;}
template <class T>bool chmin(T &a, const T &b){if(a > b){a = b; return 1;} return 0;}
template <typename T> istream &operator>>(istream &is, vector<T> &vec){for(auto &v: vec)is >> v; return is;}
template <typename T> ostream &operator<<(ostream &os, const vector<T>& vec){for(int i = 0; i < vec.size(); i++){ os << vec[i]; if(i + 1 != vec.size())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p){os << p.first << " " << p.second; return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const unordered_map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}

int ato_int(char c){
  return int(c - 'a');
}

char to_achar(int i){
  return char(i + 'a');
}

int Ato_int(char c){
  if('a' <= c && c <= 'z')return int(c - 'a');
  return int(c - 'A') + 26;
}

char to_Achar(int i){
  if(i < 26)return char(i + 'a');
  return char(i - 26 + 'A');
}

int dto_int(char c){
  return int(c - '0');
}

char to_dchar(int i){
  return char(i + '0');
}

typedef struct SuccinctBitVector_ {
  int size;
  int block = 32;
  int l = 256;
  vector<uint32_t> B;
  vector<unsigned> L, S;
  SuccinctBitVector_(){}
  SuccinctBitVector_(int size_){
    size = size_;
    B.assign((size + block - 1) / block, 0U);
    L.assign((size + l - 1) / l, 0U);
    S.assign((size + block - 1) / block, 0U);
  }
  void set_bit(int at){
    B[at / block] |= (1U << (at % block));
  }
  void build(){
    int true_count = 0;
    for(int i = 0; i < ((size + block - 1) / block) * block; i+=block){
      if(i % l == 0)L[i / l] = true_count;
      S[i / block] = true_count - L[i / l];
      true_count += __builtin_popcount(B[i / block]);
    }
  }
  bool access(int at){
    return (B[at / block] >> (at % block)) & 1U;
  }
  bool operator[](int at){
    return access(at);
  }
  // this is rank1
  int rank(int at){
    return L[at / l] + S[at / block] + __builtin_popcount((B[at / block] & ((1U << (at % block)) - 1)));
  }
  int rank(bool val, int at){
    return (val ? rank(at): at - rank(at));
  }
  int select(bool val, int x){
    if(x < 0 || x >= rank(val, size))return -1;
    int ld = 0, rd = size;
    while(rd - ld > 1){
      int md = (rd + ld) / 2;
      if(rank(val, md) >= x + 1)rd = md;
      else ld = md;
    }
    return rd - 1;
  }
  int select(int x){
    return select(1, x);
  }
  int select(bool val, int x, int l){
    return select(val, x + rank(val, l));
  }
} SuccinctBitVector;

vector<int> ato_vector(const string &s){
  vector<int> v(s.size());
  for(int i = 0; i < s.size(); i++){
    v[i] = ato_int(s[i]);
  }
  return v;
}

template <typename T>
struct WaveletMatrix{
  int n = 0;
  int len = 0;
  vector<SuccinctBitVector> mat;
  vector<int> zc;
  vector<int> bl, br;
  vector<vector<T>> sum;
  WaveletMatrix(ll m, vector<T> s){
    len = s.size();
    while((1LL<< n) <= m)n++;
    mat.resize(n);
    zc.resize(n);
    bl.resize(n);
    br.resize(n);
    sum.resize(n + 1, vector<T>(len + 1, 0));

    for(int i = 0; i < len; i++)sum[0][i + 1] = sum[0][i] + s[i];

    vector<T> l(len), r(len);
    for(int i = 0; i < n; i++){
      mat[i] = SuccinctBitVector(len + 1);
      int li = 0, ri = 0;
      for(int j = 0; j < len; j++){
        if((s[j] >> (n - i - 1)) & 1){
          r[ri++] = s[j];
          mat[i].set_bit(j);
        }else{
          l[li++] = s[j];
        }
      }
      zc[i] = li;
      mat[i].build();
      swap(l, s);
      for(int j = 0; j < ri; j++)s[li + j] = r[j];
      for(int j = 0; j < len; j++)sum[i+1][j+1] = sum[i+1][j] + s[j];
    }
  }
  T access(int i){
    int res = 0;
    for(int j = 0; j < n; j++){
      bool bit = mat[j][i];
      res = (res << 1) | bit;
      i = zc[j] * bit + mat[j].rank(bit, i);
    }
    return res;
  }
  T operator[](int i){
    return access(i);
  }
  int rank(T val, int i){
    int l = 0, r = i;
    for(int j = 0; j < n; j++){
      bl[j] = l, br[j] = r;
      bool bit = (val >> (n - j - 1)) & 1;
      l = zc[j] * bit + mat[j].rank(bit, l);
      r = zc[j] * bit + mat[j].rank(bit, r);
    }
    return r - l;
  }
  int select(T val, int i){
    rank(val, len);
    for(int j = n - 1; j >= 0; j--){
      bool bit = (val >> (n - j - 1)) & 1;
      i = mat[j].select(bit, i, bl[j]);
      if(i >= br[j] || i < 0)return -1;
      i -= bl[j];
    }
    return i;
  }
  int select(T val, int i, int l){
    return select(val, i + rank(val, l));
  }
  T quantile(int s, int e, int k){
    if(e - s <= k || k < 0)return -1;
    T res = 0;
    for(int i = 0; i < n; i++){
      int l = mat[i].rank(1, s);
      int r = mat[i].rank(1, e);
      if(r - l > k){
        s = zc[i] + l;
        e = zc[i] + r;
        res = res | (1LL << (n - i - 1));
      }else{
        k -= (r - l);
        s -= l;
        e -= r;
      }
    }
    return res;
  }
  // equal, lt, gt
  tuple<int, int, int> rankall(T x, int s, int e){
    if(s >= e)return make_tuple(0, 0, 0);
    int rank_lt = 0, rank_gt = 0;
    for(int i = 0; i < n && s < e; i++){
      bool bit = (x >> (n - i - 1)) & 1;
      int s0 = mat[i].rank(0, s);
      int s1 = s - s0;
      int e0 = mat[i].rank(0, e);
      int e1 = e - e0;
      if(bit){
        rank_lt += e0 - s0;
        s = zc[i] + s1;
        e = zc[i] + e1;
      }else{
        rank_gt += e1 - s1;
        s = s0;
        e = e0;
      }
    }
    return make_tuple(e - s - rank_lt - rank_gt, rank_lt, rank_gt);
  }
  int rangefreq(int s, int e, T mini, T maxi){
    tuple<int, int, int> maxi_t = rankall(maxi, s, e);
    tuple<int, int, int> mini_t = rankall(mini, s, e);
    return get<1>(maxi_t) - get<1>(mini_t);
  }
  int ranklt(T x, int s, int e){
    return get<1>(rankall(x, s, e));
  }
  int rankgt(T x, int s, int e){
    return get<2>(rankall(x, s, e));
  }
  T rangemax(int s, int e){
    return quantile(s, e, 0);
  }
  T rangemin(int s, int e){
    return quantile(s, e, e - s - 1);
  }
  vector<pair<T, int>> topk(int s, int e, int k){
    vector<pair<T, int>> res;
    using v_t = tuple<int, int, int, int, T>;
    auto comp = [](const v_t &a, const v_t &b){
      if(get<0>(a) != get<0>(b))return get<0>(a) < get<0>(b);
      if(get<3>(a) != get<3>(b))return get<3>(a) > get<3>(b);
      return get<3>(a) > get<3>(b);
    };
    priority_queue<v_t, vector<v_t>, decltype(comp)> pq(comp);
    pq.push(make_tuple(e - s, s, e, 0, 0));
    while(!pq.empty()){
      auto p = pq.top(); pq.pop();
      int width, li, ri, dep;
      T val;
      tie(width, li, ri, dep, val) = p;
      if(dep >= n){
        res.emplace_back(make_pair(val, ri - li));
        if(res.size() >= k)break;
        continue;
      }
      int l0 = mat[dep].rank(0, li);
      int r0 = mat[dep].rank(0, ri);
      if(l0 < r0)pq.push(make_tuple(r0 - l0, l0, r0, dep + 1, val));
      int l1 = zc[dep] + mat[dep].rank(1, li);
      int r1 = zc[dep] + mat[dep].rank(1, ri);
      if(l1 < r1)pq.push(make_tuple(r1 - l1, l1, r1, dep + 1, val | (1LL << (n - dep - 1))));
    }
    return res;
  }
  T rangesum(int s, int e, int depth, T val, T x, T y){
    if(s == e)return 0;
    if(depth == n){
      if(x <= val && val < y)return val * (e - s);
      return 0;
    }
    T nv = (1LL << (n - depth - 1)) | val;
    T nnv = ((1LL << (n - depth - 1)) - 1) | nv;
    if(nnv < x || y <= val)return 0;
    if(x <= val && nnv < y)return sum[depth][e] - sum[depth][s];
    int s0 = mat[depth].rank(0, s);
    int s1 = s - s0;
    int e0 = mat[depth].rank(0, e);
    int e1 = e - e0;
    return rangesum(s0, e0, depth + 1, val, x, y) + rangesum(zc[depth] + s1, zc[depth] + e1, depth + 1, nv, x, y);
  }
  T rangesum(int s, int e, T x, T y){
    return rangesum(s, e, 0, 0, x, y);
  }
  T prev(int s, int e, T x, T y){
    y--;
    using v_t = tuple<int, int, int, T, bool>;
    stack<v_t> st;
    st.push(make_tuple(s, e, 0, 0, true));
    while(!st.empty()){
      auto p = st.top(); st.pop();
      int li, ri, depth;
      T val;
      bool tight;
      tie(li, ri, depth, val, tight) = p;

      if(depth == n){
        if(val >= x)return val;
        continue;
      }

      bool bit = (y >> (n - depth - 1)) & 1;
      int l0 = mat[depth].rank(0, li);
      int l1 = li - l0;
      int r0 = mat[depth].rank(0, ri);
      int r1 = ri - r0;
      if(l0 != r0){
        st.push(make_tuple(l0, r0, depth + 1, (val << 1), tight && !bit));
      }
      if(l1 != r1){
        if(!tight || bit){
          st.push(make_tuple(zc[depth] + l1, zc[depth] + r1, depth + 1, ((val<<1)|1), tight));
        }
      }
    }
    return -1;
  }
  T next(int s, int e, T x, T y){
    using v_t = tuple<int, int, int, T, bool>;
    stack<v_t> st;
    st.push(make_tuple(s, e, 0, 0, true));
    while(!st.empty()){
      auto p = st.top(); st.pop();
      int li, ri, depth;
      T val;
      bool tight;
      tie(li, ri, depth, val, tight) = p;
      if(depth == n){
        if(val < y)return val;
        continue;
      }

      bool bit = (x >> (n - depth - 1)) & 1;
      int l0 = mat[depth].rank(0, li);
      int l1 = li - l0;
      int r0 = mat[depth].rank(0, ri);
      int r1 = ri - r0;
      if(l1 != r1){
        st.push(make_tuple(zc[depth] + l1, zc[depth] + r1, depth + 1, ((val<<1)|1), tight && bit));
      }
      if(l0 != r0){
        if(!tight || !bit){
          st.push(make_tuple(l0, r0, depth + 1, (val << 1), tight));
        }
      }
    }
    return -1;
  }
  vector<tuple<T, int, int>> intersect(int s1, int e1, int s2, int e2){
    using v_t = tuple<int, int, int, int, int, T>;
    vector<tuple<T, int, int>> res;
    queue<v_t> q;
    q.push(make_tuple(s1, e1, s2, e2, 0, 0));
    while(!q.empty()){
      auto p = q.front(); q.pop();
      int s_1, e_1, s_2, e_2, depth;
      T val;
      tie(s_1, e_1, s_2, e_2, depth, val) = p;
      if(depth == n){
        res.emplace_back(make_tuple(val, e_1 - s_1, e_2 - s_2));
        continue;
      }

      int s1_0 = mat[depth].rank(0, s_1);
      int e1_0 = mat[depth].rank(0, e_1);
      int s2_0 = mat[depth].rank(0, s_2);
      int e2_0 = mat[depth].rank(0, e_2);

      if(s1_0 != e1_0 && s2_0 != e2_0){
        q.push(make_tuple(s1_0, e1_0, s2_0, e2_0, depth + 1, val));
      }

      int s1_1 = s_1 - s1_0 + zc[depth];
      int e1_1 = e_1 - e1_0 + zc[depth];
      int s2_1 = s_2 - s2_0 + zc[depth];
      int e2_1 = e_2 - e2_0 + zc[depth];

      if(s1_1 != e1_1 && s2_1 != e2_1){
        q.push(make_tuple(s1_1, e1_1, s2_1, e2_1, depth + 1, val | (1LL << (n - depth - 1))));
      }
    }
    return res;
  }
  void max_dfs(int d, int s, int e, int &k, T val, vector<T> &vs){
    if(s >= e || !k)return;
    if(d == n){
      while(s++ < e && k > 0)vs.emplace_back(val), k--;
      return;
    }
    int l1 = mat[d].rank(1, s);
    int r1 = mat[d].rank(1, e);
    max_dfs(d + 1, zc[d] + l1, zc[d] + r1, k, (1LL<<(n-d-1))|val, vs);
    max_dfs(d + 1, s - l1, e - r1, k, val, vs);
  }
  vector<T> maximum(int s, int e, int k){
    if(e - s < k)k = e - s;
    if(k < 0)return {};
    vector<T> res;
    max_dfs(0, s, e, k, 0, res);
    return res;
  }
  void list_dfs(int d, int s, int e, T val, T a, T b, vector<pair<T, int>> &vs){
    if(val >= b || e - s <= 0)return;
    if(d == n){
      if(a <= val){
        vs.emplace_back(make_pair(val, e - s));
      }
      return;
    }
    T nv = val | (1LL<<(n-d-1)), nnv = nv | ((1LL<<(n-d-1))-1);
    if(nnv < a)return;
    int l0 = mat[d].rank(1, s);
    int r0 = mat[d].rank(1, e);
    list_dfs(d + 1, s - l0, e - r0, val, a, b, vs);
    list_dfs(d + 1, zc[d] + l0, zc[d] + r0, nv, a, b, vs);
  }
  vector<pair<T, int>> freq_list(int s, int e, T a, T b){
    vector<pair<T, int>> res;
    list_dfs(0, s, e, 0, a, b, res);
    return res;
  }
  vector<pair<int, T>> get_rect(int s, int e, T a, T b){
    vector<pair<T, int>> fl = freq_list(s, e, a, b);
    vector<pair<int, T>> res;
    for(auto &e: fl){
      for(int i = 0; i < e.second; i++){
        res.emplace_back(make_pair(select(e.first, i, s), e.first));
      }
    }
    return res;
  }
};

template <typename T>
struct Graph_ {
  int n;
  vector<vector<pair<int, T> > > edge;
  vector<T> dis;
  Graph_(int ns) {
    n = ns;
    edge.resize(n);
    dis.resize(n);
  }
  void dijkstra(int s){
    dijkstra(s, 0);
  }
  T dijkstra(int s, int t){
    // initialize
    fill(dis.begin(), dis.end(), -1);
    vector<bool> used;
    used.resize(n);
    fill(used.begin(), used.end(), false);
    dis[s] = 0;
    // dijkstra
    priority_queue<pair<T, int>, vector<pair<T, int> >, greater<pair<T, int> > > q;
    q.push(make_pair(0, s));
    while(!q.empty()){
      pair<T, int> p = q.top(); q.pop();
      int at = p.second;
      T distance = p.first;
      if(used[at])continue;
      used[at] = true;
      for(auto itr = edge[at].begin(); itr != edge[at].end(); ++itr){
        int to = (*itr).first;
        T cost = (*itr).second;
        if(used[to])continue;
        if(dis[to] == -1 || dis[to] > distance + cost){
          q.push(make_pair(distance + cost, to));
          dis[to] = distance + cost;
        }
      }
    }
    return dis[t];
  }
  void adde(int at, int to, T cost){
    edge[at].push_back(make_pair(to, cost));
  }
  [[deprecated("This function takes O(edge[at].size()).")]]
    void remove(int at, int to){
      int index = -1;
      for(int i = 0; i < edge[at].size(); i++){
        if(edge[at][i].first == to){
          index = i;
          break;
        }
      }
      edge[at].erase(edge[at].begin() + index);
    }
};

typedef struct Graph_<int> GraphI;
typedef struct Graph_<ll> GraphL;
typedef struct Graph_<double> GraphD;

bool comp(const Pll &a, const Pll &b){
  return a.FI < b.FI;
}

int main(int argc, char const* argv[])
{
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  INT(n); INT(m);
  GraphL graph(n);
  rep(i, m){
    INT(a); INT(b); LL(c);
    graph.adde(a, b, c);
    graph.adde(b, a, c);
  }
  graph.dijkstra(0);
  vector<ll> ds = graph.dis;
  graph.dijkstra(n - 1);
  vector<ll> de = graph.dis;
  vector<Pll> vec(n);
  rep(i, n)vec[i] = mk(ds[i], de[i]);
  sort(all(vec), comp);
  vector<ll> v(n);
  rep(i, n){
    v[i] = vec[i].SE;
  }
  WaveletMatrix<ll> w(linf, v);
  INT(q);
  rep(i, q){
    LL(fs); LL(fg);
    int r = upper_bound(all(vec), mk(fs, linf)) - vec.begin();
    cout << w.rangefreq(0, r, fg, linf) << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 59560
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

const double PI = acos(-1);
const double EPS = 1e-15;
using ll = long long;
using ull = unsigned long long;
const int inf = 2e9;
const ll INF = 2e18;
const ll MOD = 1e9+7;
const ll MOD1 = 998244353;
typedef pair<ll,ll> P;

#define rep(i,a,b) for (int i = (a); i < (b); i++)
#define rrep(i,a,b) for (int i = (a); i >= (b); i--)
#define REP(i,n) rep(i,0,n)
#define RREP(i,n) rrep(i,n,0)
#define sz(s) (s).size()
#define pb push_back
#define fi first
#define se second
//#define mp make_pair

ll n,m;
vector<P> G[100010];
ll ds[100010];
ll dt[100010];
int bit[200010];
map<ll,int> mp;
map<int,ll> mp1;
ll ans[100010];
vector<ll> work;

int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> n >> m;
  REP(i,m) {
    ll a,b,c;
    cin >> a >> b >> c;
    G[a].pb({b,c});
    G[b].pb({a,c});
  }
  fill(ds, ds + n, INF);
  fill(dt, dt + n, INF);

  priority_queue<P,vector<P>,greater<P>> pq1,pq2;
  pq1.push({0LL,0LL});
  pq2.push({0LL,n-1});

  ds[0] = 0;
  dt[n-1] = 0;

  while (!pq1.empty()) {
    P p = pq1.top();
    pq1.pop();
    ll v = p.second;
    if (ds[v] < p.first) continue;
    for (int i = 0; i < G[v].size(); i++) {
      P e = G[v][i];
      if (ds[e.fi] > ds[v] + e.se) {
        ds[e.fi] = ds[v] + e.se;
        pq1.push(P(ds[e.fi], e.fi));
      }
    }
  }

  while (!pq2.empty()) {
    P p = pq2.top();
    pq2.pop();
    ll v = p.second;
    if (dt[v] < p.first) continue;
    for (int i = 0; i < G[v].size(); i++) {
      P e = G[v][i];
      if (dt[e.fi] > dt[v] + e.se) {
        dt[e.fi] = dt[v] + e.se;
        pq2.push(P(dt[e.fi], e.fi));
      }
    }
  }

  priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>> P;
  priority_queue<pair<pair<ll,ll>,int>,vector<pair<pair<ll,ll>,int>>,greater<pair<pair<ll,ll>,int>>> Q;

  REP(i,n) {
    P.push({ds[i],dt[i]});
  }
  sort(dt,dt+n);
  int num = 1;
  REP(i,n) {
    work.pb(dt[i]);
  }

  int q;
  cin >> q;
  REP(i,q) {
    ll fs, ft;
    cin >> fs >> ft;
    Q.push({{fs,ft},i});
    work.pb(ft);
  }
  sort(work.begin(),work.end());
  REP(i,sz(work)) {
    if (!mp.count(work[i])) mp[work[i]] = num++;
  }

  int cnt = 0;
  while (!Q.empty()) {
    ll lim = Q.top().fi.fi;
    while (!P.empty() && P.top().fi <= lim) {
      ll tmp = mp[P.top().se];
      P.pop();
      cnt++;
      while (tmp <= num) {
        bit[tmp]++;
        tmp += tmp & -tmp;
      }
    }
//    cout << "------------" << endl;
//    cout << cnt << endl;
    while (!Q.empty() && Q.top().fi.fi == lim) {

      ll tmp = mp[Q.top().fi.se] - 1;
      int id = Q.top().se;
      //cout << id << " " << tmp << " ";
      ans[id] += cnt;
      while (tmp > 0) {
        ans[id] -= bit[tmp];
        tmp -= tmp & -tmp;
      }
      //cout << ans[id] << endl;
      Q.pop();
    }
  }

  REP(i,q) {
    cout << ans[i] << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 28100
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>
#include <queue>
#include <tuple>
#include <set>

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
#ifdef _DEBUG_
#define dump(val) cerr << __LINE__ << ":\t" << #val << " = " << (val) << endl
#else
#define dump(val)
#endif

using namespace std;

typedef long long int ll;
typedef pair<ll, ll> P;

template<typename T>
vector<T> make_v(size_t a, T b) {
    return vector<T>(a, b);
}

template<typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v(ts...))>(a, make_v(ts...));
}

const ll inf = 1LL << 60;

void dijkstra(int s, vector<vector<P>> &G, vector<ll> &Cost) {
    int n = G.size();
    Cost.assign(n, inf);
    Cost[s] = 0;
    priority_queue<P, vector<P>, greater<P>> pq;
    pq.emplace(0LL, s);
    while (pq.size()) {
        ll cost;
        int to;
        tie(cost, to) = pq.top();
        pq.pop();
        if (cost > Cost[to]) continue;
        for (auto p : G[to]) {
            ll ncost = p.first + cost;
            int nto = p.second;
            if (Cost[nto] > ncost) {
                Cost[nto] = ncost;
                pq.emplace(ncost, nto);
            }
        }
    }
}

class BIT {
public:
    vector<ll> data;
    BIT(int n) {
        int N = 1;
        while (N < n) {
            N *= 2;
        }
        data.resize(N, 0);
    }
    void update(int pos, ll val) {
        pos++;
        for (int p = pos; p < data.size(); p += (p & -p)) {
            data[p] += val;
        }
    }
    ll query(int pos) {
        ll ans = 0;
        pos++;
        for (int p = pos; p > 0; p -= (p & -p)) {
            ans += data[p];
        }
        return ans;
    }
};

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    vector<vector<P>> Graph(n);
    REP(i, 0, m) {
        int a, b, c;
        cin >> a >> b >> c;
        Graph[a].push_back({c, b});
        Graph[b].push_back({c, a});
    }
    vector<P> Cost(n);
    {
        vector<ll> start, goal;
        dijkstra(0, Graph, start);
        dijkstra(n - 1, Graph, goal);
        REP(i, 0, n) {
            Cost[i] = {start[i], goal[i]};
        }
        sort(Cost.begin(), Cost.end());
    }

    int q;
    cin >> q;
    vector<P> F(q);
    REP(i, 0, q) {
        cin >> F[i].first >> F[i].second;
    }
    vector<int> indices(q);
    REP(i, 0, q) {
        indices[i] = i;
    }
    sort(indices.begin(), indices.end(), [&](int a, int b) {
        return F[a] < F[b];
    });

    int an = 0;
    // 座標圧縮
    {
        vector<ll> val;
        REP(i, 0, n) {
            val.push_back(Cost[i].second);
        }
        REP(i, 0, q) {
            val.push_back(F[i].second);
        }
        sort(val.begin(), val.end());
        val.erase(unique(val.begin(), val.end()), val.end());
        an = val.size();

        REP(i, 0, n) {
            Cost[i].second = lower_bound(val.begin(), val.end(), Cost[i].second) - val.begin();
        }
        REP(i, 0, q) {
            F[i].second = lower_bound(val.begin(), val.end(), F[i].second) - val.begin();
        }
    }

    BIT bit(an + 2);

    vector<int> ans(q, 0);
    int pos = 0;
    set<ll> s;
    REP(i, 0, q) {
        int v = indices[i];
        while (pos < n && Cost[pos].first <= F[v].first) {
            bit.update(Cost[pos].second, 1);
            pos++;
        }
        ans[v] = pos - bit.query(F[v].second - 1);
    }
    REP(i, 0, q) {
        cout << ans[i] << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 16848
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

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

const ll INF = 1e18;

const int MAX_N = 1e5 + 10;
struct Edge { int to; ll cost; };
vector<Edge> es[MAX_N];

ll ds[MAX_N];
ll dg[MAX_N];


#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/tag_and_trait.hpp>
using namespace __gnu_pbds;
using Tree = tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    rep(i, m) {
        int a, b;
        ll c;
        cin >> a >> b >> c;
        es[a].pb({b, c});
        es[b].pb({a, c});
    }
    auto dijkstra = [&] (int root, ll d[]) {
        rep(i, MAX_N) d[i] = INF;
        typedef pair<ll, int> P; //dist, from
        priority_queue<P, vector<P>, greater<P> > q;
        d[root] = 0LL;
        q.push({0LL, root});
        while (!q.empty()) {
            auto p = q.top(); q.pop();
            int prv = p.se;
            auto cost = p.fi;
            if (d[prv] < p.fi) continue;
            for (auto& e : es[prv]) {
                int to = e.to;
                auto dist = e.cost + cost;
                if (dist < d[to]) {
                    d[to] = dist;
                    q.push({dist, to});
                }
            }
        }
    };
    dijkstra(0, ds);
    dijkstra(n-1, dg);
    using P = pair<ll, ll>;
    vector<P> v(n);
    rep(i, n) v[i] = {ds[i], dg[i]};
    sort(all(v));
    int Q;
    cin >> Q;
    vector<pair<P, int>> query(Q);
    rep(i, Q) {
        ll s, g;
        cin >> s >> g;
        query[i] = {{s, g}, i};
    }
    sort(all(query));


    map<ll, ll> mp;
    rep(i, n) mp[v[i].se]++;
    rep(i, Q) mp[query[i].fi.se]++;
    int sz = 0;
    for(auto&& p: mp) p.se = sz++;

    vector<int> ans(Q);
    Tree st;
    int cur = 0;
    rep(i, Q) {
        ll s = query[i].fi.fi, g = query[i].fi.se;
        int idx = query[i].se;
        while(cur < n && v[cur].fi <= s) st.insert(mp[v[cur++].se] * MAX_N + cur);
        int tmp = st.order_of_key(mp[g]*MAX_N);
        ans[idx] = (int)st.size() - tmp;
    }
    rep(i, Q) cout << ans[i] << '\n';
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 31940
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
typedef pair<ll, ll> Pll;
typedef vector<int> Vi;
//typedef tuple<int, int, int> T;
#define FOR(i,s,x) for(int i=s;i<(int)(x);i++)
#define REP(i,x) FOR(i,0,x)
#define ALL(c) c.begin(), c.end()
#define DUMP( x ) cerr << #x << " = " << ( x ) << endl
#define UNIQUE(c) sort(ALL(c)), c.erase(unique(ALL(c)), c.end())

const int dr[4] = {-1, 0, 1, 0};
const int dc[4] = {0, 1, 0, -1};

// graph by adjacency list
template <typename T>
struct Edge {
  int dst; T weight;
  Edge(int dst, T weight) : dst(dst), weight(weight) { }
  bool operator < (const Edge<T> &e) const {
    return weight > e.weight;
  }
};

template <typename T>
struct Graph {
  int V;
  vector<vector<Edge<T>>> E;
  Graph(int V) : V(V) { E.resize(V); }
  void add_edge(int src, int dst, T weight) {
    E[src].emplace_back(dst, weight);
  }
};


const ll INF = 1e12;

template <typename T>
struct Node {
  int v; T dist;
  Node(int v, T dist) : v(v), dist(dist) { };
  bool operator < (const Node<T> &n) const {
    return dist > n.dist; // reverse
  }
};

template <typename T>
struct ShortestPath {
  const Graph<T> g;
  vector<T> dist;
  vector<int> prev;

  ShortestPath(const Graph<T> &g) : g(g) { dist.resize(g.V), prev.resize(g.V); }

  void run(int start) {
    priority_queue<Node<T>> que;
    dist.assign(g.V, INF);
    dist[start] = 0;
    que.emplace(start, 0);
    prev[0] = -1;

    while (!que.empty()) {
      Node<T> n = que.top(); que.pop();
      int v = n.v; T cost = n.dist;
      if (dist[v] < cost) continue;
      for (Edge<T> e : g.E[v]) {
        if (dist[v] < dist[e.dst] - e.weight) {
          dist[e.dst] = dist[v] + e.weight;
          prev[e.dst] = v;
          que.emplace(e.dst, dist[e.dst]);
        }
      }
    }
  }

  vector<int> build_path(int goal) {
    vector<int> path;
    for (int v = goal; v != -1; v = prev[v]) {
      path.emplace_back(v);
    }
    reverse(path.begin(), path.end());
    return path;
  }
};

/**
 * @brief type for input data
 */
template <typename T>
struct Data {
  using type = T;
  type data;

  /**
   * Constructor for Data
   * @param data Data should be std::array
   */
  Data(type &data) : data(data) {}

  /**
   * Comparing function for data.
   * This function compares two data in lexicographical order.
   *
   * @param data1 First data for comparing
   * @param data2 Second data for comparing
   * @param base Start dimension for comparing.
   *
   * @return If data1 < data1 in lexicographical order, then true, otherwise false.
   */
  static bool compare (const Data<type> &data1, const Data<type> &data2, size_t base = 1) {
    const size_t dim = data1.data.size();
    for (size_t i = 0; i < dim; i++) {
      if (data1.data[(i + base) % dim] != data2.data[(i + base) % dim]) {
        return data1.data[(i + base) % dim] < data2.data[(i + base) % dim];
      }
    }
    return false;
  }
  /**
   * == operator for data
   */
  bool operator==(const Data<type> &data) const {
    return this->data == data.data;
  }
};

/**
 * Orthogonal Region for
 */
template <typename T>
struct Region {
  T low, high;
  /**
   * Constructor for struct Region
   * If d = low.size(), then corresponding orthogonal region R is following.
   * R = [low[0], high[0]] * [low[1], high[1]] * ... * [low[d-1], high[d-1]]
   *
   * @param low lower borders of orthogonal region
   * @param high higher borders of orthogonal region
   */
  Region(T &low, T &high) : low(low), high(high) {};

  /**
   * Checking Function of Inclusion for Data and Region.
   *
   * @param data A data
   * @return If this region include the data, then return true, otherwise return false.
   */
  bool include(T data) const {
    size_t dim = this->low.size();
    for (size_t i = 0; i < dim; i++) {
      if (data[i] < low[i] or high[i] < data[i]) {
        return false;
      }
    }
    return true;
  }

  /**
   * Checking Function of Inclusion for Two Regions.
   *
   * @param region A region.
   * @return If this region include the given region, then return true, otherwise return false.
   */
  bool include(const Region<T> &region) const {
    size_t dim = this->low.size();
    for (size_t bit = 0; bit < (1U << dim); bit++) {
      T data;
      for (size_t i = 0; i < dim; i++) {
        if (bit >> i & 1) {
          data[i] = region.low[i];
        } else {
          data[i] = region.high[i];
        }
      }
      if (not this->include(data)) {
        return false;
      }
    }
    return true;
  }

  /**
   * Cheking Function of Overlapping for Two Regions.
   *
   * @param region A region.
   * @return If this region overlaps the given region, then return true, otherwise return false.
   */
  bool overlap(Region<T> &region) const {
    size_t dim = this->low.size();
    for (size_t bit = 0; bit < (1U << dim); bit++) {
      T data;
      for (size_t i = 0; i < dim; i++) {
        if (bit >> i & 1) {
          data[i] = region.low[i];
        } else {
          data[i] = region.high[i];
        }
      }
      if (this->include(data)) {
        return true;
      }
    }
    return false;
  }

  /**
   * overloading of << operator
   */
  friend std::ostream& operator<<(std::ostream& os, const Region<T> &region) {
    for (size_t i = 0; i < region.low.size(); i++) {
      if (i > 0) {
        os << 'x';
      }
      os << '[' << region.low[i] << ',' << region.high[i] << ']';
    }
    return os;
  }
};

struct RangeTreeNode {
  size_t idx;                   /**< Node index */
  int node_count;
  RangeTreeNode *assoc;         /**< Pointer of associated structure */
  RangeTreeNode *left, *right;  /**< Pointer of left & right node */
  RangeTreeNode(size_t idx) : idx(idx), node_count(1), assoc(nullptr), left(nullptr), right(nullptr) {}
  bool is_leaf_node() const {
    return left == nullptr and right == nullptr;
  }
};

template <typename DataType>
struct RangeTree {
  using T = typename DataType::type;
  using VT = typename T::value_type;
  size_t dim;                   /**< Dimension of Data */
  std::vector<DataType> data;   /**< Data in range tree */
  VT min_range, max_range;      /**< Initial Range for range query */
  RangeTreeNode *root;          /**< Root Node */

  RangeTree(size_t dim = 2, VT min_range = std::numeric_limits<VT>::min(), VT max_range = std::numeric_limits<VT>::max()) : dim(dim), min_range(min_range), max_range(max_range) {}

  RangeTreeNode *build_1d(std::vector<size_t> &data, size_t low, size_t high) {
    if (low + 1 == high) {
      return new RangeTreeNode(data[low]);
    }
    size_t median = (low + high) / 2;
    RangeTreeNode *node = new RangeTreeNode(data[median]);
    if (low < median) {
      node->left = build_1d(data, low, median);
      node->node_count += node->left->node_count;
    }
    if (median + 1 < high) {
      node->right = build_1d(data, median + 1, high);
      node->node_count += node->right->node_count;
    }
    return node;
  }

  RangeTreeNode *build(std::vector<std::vector<size_t>> &data, size_t depth) {
    RangeTreeNode *assoc;
    if (depth + 2 ==  this->dim) {
      assoc = build_1d(data[depth + 1], 0, data[0].size());
    } else {
      assoc = build(data, depth + 1);
    }

    if (data[0].size() == 1) {
      RangeTreeNode *node = new RangeTreeNode(data[0][0]);
      node->assoc = new RangeTreeNode(data[0][0]);
      return node;
    }
    std::vector<std::vector<size_t>> left_data(this->dim), right_data(this->dim);
    size_t median_idx = static_cast<size_t>(static_cast<int>(data[0].size()) / 2);
    size_t median = data[depth % this->dim][median_idx];
    for (size_t i = 0; i < this->dim; i++) {
      for (size_t j : data[i]) {
        if (DataType::compare(this->data[j], this->data[median], depth % this->dim)) {
          left_data[i].emplace_back(j);
        } else if (not (this->data[j] == this->data[median])) {
          right_data[i].emplace_back(j);
        }
      }
    }
    RangeTreeNode *node = new RangeTreeNode(median);
    if (left_data[0].size()) {
      node->left = build(left_data, depth);
      node->node_count += node->left->node_count;
    }
    if (right_data[0].size()) {
      node->right = build(right_data, depth);
      node->node_count += node->right->node_count;
    }
    node->assoc = assoc;
    return node;
  }

  void build(std::vector<DataType> &data) {
    assert(data.size() > 0);
    std::vector<std::vector<size_t>> _data(this->dim, std::vector<size_t>(data.size()));
    this->data = std::move(data);
    for (size_t i = 0; i < this->dim; i++) {
      std::iota(_data[i].begin(), _data[i].end(), 0);
      sort(_data[i].begin(), _data[i].end(),
           [&](const size_t &a, const size_t &b) {
             return DataType::compare(this->data[a], this->data[b], i);
           });
    }
    this->root = build(_data, 0);
  }

  void output(bool assoc = true) const {
    output(this->root, assoc);
  }

  void output(RangeTreeNode *node, bool assoc = true) const {
    if (node == nullptr) return ;
    std::cout << "idx: " << node->idx << ", (";
    for (size_t i = 0; i < this->dim; i++) {
      if (i > 0) {
        std::cout << ',';
      }
      std::cout << this->data[node->idx].data[i];
    }
    std::cout << ") ";
    if (not node->is_leaf_node()) {
      std::cout << "(left, right) = (" << (node->left == nullptr ? -1 : (int)node->left->idx) << ',' << (node->right == nullptr ? -1 : (int)node->right->idx) << ')' << std::endl;
      if (node->assoc != nullptr and assoc) {
        std::cout << "assoc start" << std::endl;
        output(node->assoc, assoc);
        std::cout << "assoc end" << std::endl;
      }
      output(node->left, assoc);
      output(node->right, assoc);

    } else {
      std::cout << std::endl;
    }
  }

  RangeTreeNode *find_split_node(RangeTreeNode *node, size_t dim, DataType &low, DataType &high) const {

    while (node != nullptr and (DataType::compare(this->data[node->idx], low, dim) or
                                not DataType::compare(this->data[node->idx], high, dim))) {
      if (DataType::compare(this->data[node->idx], low, dim)) {
        node = node->right;
      } else {
        node = node->left;
      }
    }
    return node;
  }

  void report_subtree(RangeTreeNode *node, std::vector<size_t> &output) const {
    if (node == nullptr) return ;
    output.emplace_back(node->idx);
    report_subtree(node->left, output);
    report_subtree(node->right, output);
  }

  void query(Region<T> &query_region, std::vector<size_t> &output) const {
    query(this->root, query_region, 0, output);
  }

  int count_query(Region<T> &query_region) const {
    return count_query(this->root, query_region, 0);
  }

  void query(RangeTreeNode *node, Region<T> &query_region, size_t dim, std::vector<size_t> &output) const {
    if (node == nullptr) {
      return ;
    }
    T low_, high_;
    low_.fill(this->min_range), high_.fill(this->max_range);
    low_[dim] = query_region.low[dim], high_[dim] = query_region.high[dim];
    DataType low(low_), high(high_);

    RangeTreeNode *split_node = this->find_split_node(node, dim, low, high);

    if (split_node == nullptr) {
      return ;
    }

    //std::cout << "split: " << split_node->idx << ' ' << dim << std::endl;
    if (query_region.include(this->data[split_node->idx].data)) {
      output.emplace_back(split_node->idx);
    }

    node = split_node->left;
    while (node != nullptr) {
      //std::cout << "left: " << node->idx << ' ' << dim << std::endl;
      if (query_region.include(this->data[node->idx].data)) {
        output.emplace_back(node->idx);
      }

      if (DataType::compare(this->data[node->idx], low, dim)) {
        node = node->right;
      } else {
        if (dim + 1 == this->dim) {
          report_subtree(node->right, output);
        } else if (node->right != nullptr) {
          query(node->right->assoc, query_region, dim + 1, output);
        }
        node = node->left;
      }
    }

    node = split_node->right;
    while (node != nullptr) {
      //std::cout << "right: " << node->idx << ' ' << dim << std::endl;
      if (query_region.include(this->data[node->idx].data)) {
        output.emplace_back(node->idx);
      }
      if (DataType::compare(this->data[node->idx], high, dim)) {
        if (dim + 1 == this->dim) {
          report_subtree(node->left, output);
        } else if (node->left != nullptr) {
          query(node->left->assoc, query_region, dim + 1, output);
        }
        node = node->right;
      } else {
        node = node->left;
      }
    }
  }

  int count_query(RangeTreeNode *node, Region<T> &query_region, size_t dim) const {
    if (node == nullptr) {
      return 0;
    }
    T low_, high_;
    low_.fill(this->min_range), high_.fill(this->max_range);
    low_[dim] = query_region.low[dim], high_[dim] = query_region.high[dim];
    DataType low(low_), high(high_);

    RangeTreeNode *split_node = this->find_split_node(node, dim, low, high);

    if (split_node == nullptr) {
      return 0;
    }

    int node_count = 0;
    //std::cout << "split: " << split_node->idx << ' ' << dim << std::endl;
    if (query_region.include(this->data[split_node->idx].data)) {
      node_count++;
    }

    node = split_node->left;
    while (node != nullptr) {
      //std::cout << "left: " << node->idx << ' ' << dim << std::endl;
      if (query_region.include(this->data[node->idx].data)) {
        node_count++;
      }

      if (DataType::compare(this->data[node->idx], low, dim)) {
        node = node->right;
      } else {
        if (dim + 1 == this->dim) {
          node_count += node->right == nullptr ? 0 : node->right->node_count;
        } else if (node->right != nullptr) {
          node_count += count_query(node->right->assoc, query_region, dim + 1);
        }
        node = node->left;
      }
    }

    node = split_node->right;
    while (node != nullptr) {
      //std::cout << "right: " << node->idx << ' ' << dim << std::endl;
      if (query_region.include(this->data[node->idx].data)) {
        node_count++;
      }
      if (DataType::compare(this->data[node->idx], high, dim)) {
        if (dim + 1 == this->dim) {
          node_count += node->left == nullptr ? 0 : node->left->node_count;
        } else if (node->left != nullptr) {
          node_count += count_query(node->left->assoc, query_region, dim + 1);
        }
        node = node->right;
      } else {
        node = node->left;
      }
    }

    return node_count;
  }

};

int main() {
  // use scanf in CodeForces!
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N, M; cin >> N >> M;
  Graph<ll> g1(N), g2(N);
  REP(i, M) {
    int a, b; ll c; cin >> a >> b >> c;
    g1.add_edge(a, b, c);
    g1.add_edge(b, a, c);
    g2.add_edge(a, b, c);
    g2.add_edge(b, a, c);
  }

  ShortestPath<ll> sp1(g1), sp2(g2);
  sp1.run(0), sp2.run(N - 1);

  using DataType = Data<std::array<ll, 3>>;
  RangeTree<DataType> range_tree(2, 0);
  std::vector<DataType> points;
  REP(i, N) {
    DataType::type tmp = {sp1.dist[i], sp2.dist[i], i};
    points.emplace_back(DataType(tmp));
  }
  range_tree.build(points);
  int Q; cin >> Q;
  REP(i, Q) {
    ll fs, gs; cin >> fs >> gs;
    DataType::type low = {range_tree.min_range, gs, 0}, high = {fs, range_tree.max_range, N - 1};
    Region<DataType::type> query_region(low, high);
    //std::vector<size_t> out;
    //range_tree.query(query_region, out);
    //std::cout << out.size() << std::endl;
    std::cout << range_tree.count_query(query_region) << std::endl;
  }
  return 0;
}
accuracy: 1
time_ms: 720
memory_kb: 121748
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
typedef pair<ll, ll> Pll;
typedef vector<int> Vi;
//typedef tuple<int, int, int> T;
#define FOR(i,s,x) for(int i=s;i<(int)(x);i++)
#define REP(i,x) FOR(i,0,x)
#define ALL(c) c.begin(), c.end()
#define DUMP( x ) cerr << #x << " = " << ( x ) << endl
#define UNIQUE(c) sort(ALL(c)), c.erase(unique(ALL(c)), c.end())

const int dr[4] = {-1, 0, 1, 0};
const int dc[4] = {0, 1, 0, -1};

// graph by adjacency list
template <typename T>
struct Edge {
  int dst; T weight;
  Edge(int dst, T weight) : dst(dst), weight(weight) { }
  bool operator < (const Edge<T> &e) const {
    return weight > e.weight;
  }
};

template <typename T>
struct Graph {
  int V;
  vector<vector<Edge<T>>> E;
  Graph(int V) : V(V) { E.resize(V); }
  void add_edge(int src, int dst, T weight) {
    E[src].emplace_back(dst, weight);
  }
};


#define INF INT_MAX

template <typename T>
struct Node {
  int v; T dist;
  Node(int v, T dist) : v(v), dist(dist) { };
  bool operator < (const Node<T> &n) const {
    return dist > n.dist; // reverse
  }
};

template <typename T>
struct ShortestPath {
  const Graph<T> g;
  vector<T> dist;
  vector<int> prev;

  ShortestPath(const Graph<T> &g) : g(g) { dist.resize(g.V), prev.resize(g.V); }

  void run(int start) {
    priority_queue<Node<T>> que;
    dist.assign(g.V, INF);
    dist[start] = 0;
    que.emplace(start, 0);
    prev[0] = -1;

    while (!que.empty()) {
      Node<T> n = que.top(); que.pop();
      int v = n.v; T cost = n.dist;
      if (dist[v] < cost) continue;
      for (Edge<T> e : g.E[v]) {
        if (dist[v] < dist[e.dst] - e.weight) {
          dist[e.dst] = dist[v] + e.weight;
          prev[e.dst] = v;
          que.emplace(e.dst, dist[e.dst]);
        }
      }
    }
  }

  vector<int> build_path(int goal) {
    vector<int> path;
    for (int v = goal; v != -1; v = prev[v]) {
      path.emplace_back(v);
    }
    reverse(path.begin(), path.end());
    return path;
  }
};

/**
 * @brief type for input data
 */
template <typename T>
struct Data {
  using type = T;
  type data;

  /**
   * Constructor for Data
   * @param data Data should be std::array
   */
  Data(type &data) : data(data) {}

  /**
   * Comparing function for data.
   * This function compares two data in lexicographical order.
   *
   * @param data1 First data for comparing
   * @param data2 Second data for comparing
   * @param base Start dimension for comparing.
   *
   * @return If data1 < data1 in lexicographical order, then true, otherwise false.
   */
  static bool compare (const Data<type> &data1, const Data<type> &data2, size_t base = 1) {
    const size_t dim = data1.data.size();
    for (size_t i = 0; i < dim; i++) {
      if (data1.data[(i + base) % dim] != data2.data[(i + base) % dim]) {
        return data1.data[(i + base) % dim] < data2.data[(i + base) % dim];
      }
    }
    return false;
  }
  /**
   * == operator for data
   */
  bool operator==(const Data<type> &data) const {
    return this->data == data.data;
  }
};

/**
 * Orthogonal Region for
 */
template <typename T>
struct Region {
  T low, high;
  /**
   * Constructor for struct Region
   * If d = low.size(), then corresponding orthogonal region R is following.
   * R = [low[0], high[0]] * [low[1], high[1]] * ... * [low[d-1], high[d-1]]
   *
   * @param low lower borders of orthogonal region
   * @param high higher borders of orthogonal region
   */
  Region(T &low, T &high) : low(low), high(high) {};

  /**
   * Checking Function of Inclusion for Data and Region.
   *
   * @param data A data
   * @return If this region include the data, then return true, otherwise return false.
   */
  bool include(T data) const {
    size_t dim = this->low.size();
    for (size_t i = 0; i < dim; i++) {
      if (data[i] < low[i] or high[i] < data[i]) {
        return false;
      }
    }
    return true;
  }

  /**
   * Checking Function of Inclusion for Two Regions.
   *
   * @param region A region.
   * @return If this region include the given region, then return true, otherwise return false.
   */
  bool include(const Region<T> &region) const {
    size_t dim = this->low.size();
    for (size_t bit = 0; bit < (1U << dim); bit++) {
      T data;
      for (size_t i = 0; i < dim; i++) {
        if (bit >> i & 1) {
          data[i] = region.low[i];
        } else {
          data[i] = region.high[i];
        }
      }
      if (not this->include(data)) {
        return false;
      }
    }
    return true;
  }

  /**
   * Cheking Function of Overlapping for Two Regions.
   *
   * @param region A region.
   * @return If this region overlaps the given region, then return true, otherwise return false.
   */
  bool overlap(Region<T> &region) const {
    size_t dim = this->low.size();
    for (size_t bit = 0; bit < (1U << dim); bit++) {
      T data;
      for (size_t i = 0; i < dim; i++) {
        if (bit >> i & 1) {
          data[i] = region.low[i];
        } else {
          data[i] = region.high[i];
        }
      }
      if (this->include(data)) {
        return true;
      }
    }
    return false;
  }

  /**
   * overloading of << operator
   */
  friend std::ostream& operator<<(std::ostream& os, const Region<T> &region) {
    for (size_t i = 0; i < region.low.size(); i++) {
      if (i > 0) {
        os << 'x';
      }
      os << '[' << region.low[i] << ',' << region.high[i] << ']';
    }
    return os;
  }
};

struct RangeTreeNode {
  size_t idx;                   /**< Node index */
  int node_count;
  RangeTreeNode *assoc;         /**< Pointer of associated structure */
  RangeTreeNode *left, *right;  /**< Pointer of left & right node */
  RangeTreeNode(size_t idx) : idx(idx), node_count(1), assoc(nullptr), left(nullptr), right(nullptr) {}
  bool is_leaf_node() const {
    return left == nullptr and right == nullptr;
  }
};

template <typename DataType>
struct RangeTree {
  using T = typename DataType::type;
  using VT = typename T::value_type;
  size_t dim;                   /**< Dimension of Data */
  std::vector<DataType> data;   /**< Data in range tree */
  VT min_range, max_range;      /**< Initial Range for range query */
  RangeTreeNode *root;          /**< Root Node */

  RangeTree(size_t dim = 2, VT min_range = std::numeric_limits<VT>::min(), VT max_range = std::numeric_limits<VT>::max()) : dim(dim), min_range(min_range), max_range(max_range) {}

  RangeTreeNode *build_1d(std::vector<size_t> &data, size_t low, size_t high) {
    if (low + 1 == high) {
      return new RangeTreeNode(data[low]);
    }
    size_t median = (low + high) / 2;
    RangeTreeNode *node = new RangeTreeNode(data[median]);
    if (low < median) {
      node->left = build_1d(data, low, median);
      node->node_count += node->left->node_count;
    }
    if (median + 1 < high) {
      node->right = build_1d(data, median + 1, high);
      node->node_count += node->right->node_count;
    }
    return node;
  }

  RangeTreeNode *build(std::vector<std::vector<size_t>> &data, size_t depth) {
    RangeTreeNode *assoc;
    if (depth + 2 ==  this->dim) {
      assoc = build_1d(data[depth + 1], 0, data[0].size());
    } else {
      assoc = build(data, depth + 1);
    }

    if (data[0].size() == 1) {
      RangeTreeNode *node = new RangeTreeNode(data[0][0]);
      node->assoc = new RangeTreeNode(data[0][0]);
      return node;
    }
    std::vector<std::vector<size_t>> left_data(this->dim), right_data(this->dim);
    size_t median_idx = static_cast<size_t>(static_cast<int>(data[0].size()) / 2);
    size_t median = data[depth % this->dim][median_idx];
    for (size_t i = 0; i < this->dim; i++) {
      for (size_t j : data[i]) {
        if (DataType::compare(this->data[j], this->data[median], depth % this->dim)) {
          left_data[i].emplace_back(j);
        } else if (not (this->data[j] == this->data[median])) {
          right_data[i].emplace_back(j);
        }
      }
    }
    RangeTreeNode *node = new RangeTreeNode(median);
    if (left_data[0].size()) {
      node->left = build(left_data, depth);
      node->node_count += node->left->node_count;
    }
    if (right_data[0].size()) {
      node->right = build(right_data, depth);
      node->node_count += node->right->node_count;
    }
    node->assoc = assoc;
    return node;
  }

  void build(std::vector<DataType> &data) {
    assert(data.size() > 0);
    std::vector<std::vector<size_t>> _data(this->dim, std::vector<size_t>(data.size()));
    this->data = std::move(data);
    for (size_t i = 0; i < this->dim; i++) {
      std::iota(_data[i].begin(), _data[i].end(), 0);
      sort(_data[i].begin(), _data[i].end(),
           [&](const size_t &a, const size_t &b) {
             return DataType::compare(this->data[a], this->data[b], i);
           });
    }
    this->root = build(_data, 0);
  }

  void output(bool assoc = true) const {
    output(this->root, assoc);
  }

  void output(RangeTreeNode *node, bool assoc = true) const {
    if (node == nullptr) return ;
    std::cout << "idx: " << node->idx << ", (";
    for (size_t i = 0; i < this->dim; i++) {
      if (i > 0) {
        std::cout << ',';
      }
      std::cout << this->data[node->idx].data[i];
    }
    std::cout << ") ";
    if (not node->is_leaf_node()) {
      std::cout << "(left, right) = (" << (node->left == nullptr ? -1 : (int)node->left->idx) << ',' << (node->right == nullptr ? -1 : (int)node->right->idx) << ')' << std::endl;
      if (node->assoc != nullptr and assoc) {
        std::cout << "assoc start" << std::endl;
        output(node->assoc, assoc);
        std::cout << "assoc end" << std::endl;
      }
      output(node->left, assoc);
      output(node->right, assoc);

    } else {
      std::cout << std::endl;
    }
  }

  RangeTreeNode *find_split_node(RangeTreeNode *node, size_t dim, DataType &low, DataType &high) const {

    while (node != nullptr and (DataType::compare(this->data[node->idx], low, dim) or
                                not DataType::compare(this->data[node->idx], high, dim))) {
      if (DataType::compare(this->data[node->idx], low, dim)) {
        node = node->right;
      } else {
        node = node->left;
      }
    }
    return node;
  }

  void report_subtree(RangeTreeNode *node, std::vector<size_t> &output) const {
    if (node == nullptr) return ;
    output.emplace_back(node->idx);
    report_subtree(node->left, output);
    report_subtree(node->right, output);
  }

  void query(Region<T> &query_region, std::vector<size_t> &output) const {
    query(this->root, query_region, 0, output);
  }

  int count_query(Region<T> &query_region) const {
    return count_query(this->root, query_region, 0);
  }

  void query(RangeTreeNode *node, Region<T> &query_region, size_t dim, std::vector<size_t> &output) const {
    if (node == nullptr) {
      return ;
    }
    T low_, high_;
    low_.fill(this->min_range), high_.fill(this->max_range);
    low_[dim] = query_region.low[dim], high_[dim] = query_region.high[dim];
    DataType low(low_), high(high_);

    RangeTreeNode *split_node = this->find_split_node(node, dim, low, high);

    if (split_node == nullptr) {
      return ;
    }

    //std::cout << "split: " << split_node->idx << ' ' << dim << std::endl;
    if (query_region.include(this->data[split_node->idx].data)) {
      output.emplace_back(split_node->idx);
    }

    node = split_node->left;
    while (node != nullptr) {
      //std::cout << "left: " << node->idx << ' ' << dim << std::endl;
      if (query_region.include(this->data[node->idx].data)) {
        output.emplace_back(node->idx);
      }

      if (DataType::compare(this->data[node->idx], low, dim)) {
        node = node->right;
      } else {
        if (dim + 1 == this->dim) {
          report_subtree(node->right, output);
        } else if (node->right != nullptr) {
          query(node->right->assoc, query_region, dim + 1, output);
        }
        node = node->left;
      }
    }

    node = split_node->right;
    while (node != nullptr) {
      //std::cout << "right: " << node->idx << ' ' << dim << std::endl;
      if (query_region.include(this->data[node->idx].data)) {
        output.emplace_back(node->idx);
      }
      if (DataType::compare(this->data[node->idx], high, dim)) {
        if (dim + 1 == this->dim) {
          report_subtree(node->left, output);
        } else if (node->left != nullptr) {
          query(node->left->assoc, query_region, dim + 1, output);
        }
        node = node->right;
      } else {
        node = node->left;
      }
    }
  }

  int count_query(RangeTreeNode *node, Region<T> &query_region, size_t dim) const {
    if (node == nullptr) {
      return 0;
    }
    T low_, high_;
    low_.fill(this->min_range), high_.fill(this->max_range);
    low_[dim] = query_region.low[dim], high_[dim] = query_region.high[dim];
    DataType low(low_), high(high_);

    RangeTreeNode *split_node = this->find_split_node(node, dim, low, high);

    if (split_node == nullptr) {
      return 0;
    }

    int node_count = 0;
    //std::cout << "split: " << split_node->idx << ' ' << dim << std::endl;
    if (query_region.include(this->data[split_node->idx].data)) {
      node_count++;
    }

    node = split_node->left;
    while (node != nullptr) {
      //std::cout << "left: " << node->idx << ' ' << dim << std::endl;
      if (query_region.include(this->data[node->idx].data)) {
        node_count++;
      }

      if (DataType::compare(this->data[node->idx], low, dim)) {
        node = node->right;
      } else {
        if (dim + 1 == this->dim) {
          node_count += node->right == nullptr ? 0 : node->right->node_count;
        } else if (node->right != nullptr) {
          node_count += count_query(node->right->assoc, query_region, dim + 1);
        }
        node = node->left;
      }
    }

    node = split_node->right;
    while (node != nullptr) {
      //std::cout << "right: " << node->idx << ' ' << dim << std::endl;
      if (query_region.include(this->data[node->idx].data)) {
        node_count++;
      }
      if (DataType::compare(this->data[node->idx], high, dim)) {
        if (dim + 1 == this->dim) {
          node_count += node->left == nullptr ? 0 : node->left->node_count;
        } else if (node->left != nullptr) {
          node_count += count_query(node->left->assoc, query_region, dim + 1);
        }
        node = node->right;
      } else {
        node = node->left;
      }
    }

    return node_count;
  }

};

int main() {
  // use scanf in CodeForces!
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N, M; cin >> N >> M;
  Graph<ll> g1(N), g2(N);
  REP(i, M) {
    int a, b; ll c; cin >> a >> b >> c;
    g1.add_edge(a, b, c);
    g1.add_edge(b, a, c);
    g2.add_edge(a, b, c);
    g2.add_edge(b, a, c);
  }

  ShortestPath<ll> sp1(g1), sp2(g2);
  sp1.run(0), sp2.run(N - 1);

  using DataType = Data<std::array<ll, 3>>;
  RangeTree<DataType> range_tree(2, 0);
  std::vector<DataType> points;
  REP(i, N) {
    DataType::type tmp = {sp1.dist[i], sp2.dist[i], i};
    points.emplace_back(DataType(tmp));
  }
  range_tree.build(points);
  int Q; cin >> Q;
  REP(i, Q) {
    ll fs, gs; cin >> fs >> gs;
    DataType::type low = {range_tree.min_range, gs, 0}, high = {fs, range_tree.max_range, N - 1};
    Region<DataType::type> query_region(low, high);
    //std::vector<size_t> out;
    //range_tree.query(query_region, out);
    //std::cout << out.size() << std::endl;
    std::cout << range_tree.count_query(query_region) << std::endl;
  }
  return 0;
}
accuracy: 0.9777777777777777
time_ms: 740
memory_kb: 121660
final_rank: 13

code_snippet: #include <stdio.h>
#include <vector>
#include <utility>
#include <algorithm>
#include <queue>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pi;
#define F first
#define S second
#define PB push_back
const int N=1e5+10;
const ll INF=1LL<<60;
ll now=12394129385729LL;
struct node{
    node* l;
    node* r;
    int size;
    ll val;
    node(ll n){
        l=r=nullptr;
        size=1;
        val=n;
    }
    void pull(){
        size=1;
        if(l)size+=l->size;
        if(r)size+=r->size;
        return ;
    }
};
bool ran(int a,int b){
    now^=12394817923847LL;
    now+=12937417834292LL;
    return (now%=(a+b))>=b;
}
node* merge(node* a,node* b){
    if(!a)return b;
    if(!b)return a;
    if(ran(a->size,b->size)){
        a->r=merge(a->r,b);
        a->pull();
        return a;
    }
    else{
        b->l=merge(a,b->l);
        b->pull();
        return b;
    }
}
void split(node* s,ll x,node* &a,node* &b){
    if(!s){
        a=b=nullptr;
        return ;
    }
    if(x>s->val){
        a=s;
        split(s->r,x,a->r,b);
        a->pull();
    }
    else{
        b=s;
        split(s->l,x,a,b->l);
        b->pull();
    }
    return ;
}
int query(node* s,ll x){
    if(!s)return 0;
    int ans=0;
    if(s->val>=x){
        if(s->l)ans+=query(s->l,x);
        ans++;
        if(s->r)ans+=s->r->size;
    }
    else if(s->r)ans+=query(s->r,x);
    return ans;
}
int main(){
    int n,m,q,a,b,c,ans[N];
    node* root=nullptr,*l,*r;
    priority_queue<pll,vector<pll>,greater<pll>>pq;
    pll temp,s[N];
    pair<pll,int> ask[N];
    bitset<N> went;
    vector<pi>graph[N];
    scanf("%d%d",&n,&m);
    while(m--){
        scanf("%d%d%d",&a,&b,&c);
        graph[a].PB({b,c});
        graph[b].PB({a,c});
    }
    for(int i=0;i<n;i++)s[i]={INF,INF};
    s[0].F=0;
    pq.push({0,0});
    went.reset();
    while(!pq.empty()){
        temp=pq.top();
        pq.pop();
        if(went[temp.S])continue;
        went[temp.S]=true;
        for(pi i:graph[temp.S])if(!went[i.F]&&s[temp.S].F+i.S<s[i.F].F){
            s[i.F].F=s[temp.S].F+i.S;
            pq.push({s[i.F].F,i.F});
        }
    }
    went.reset();
    pq.push({0,n-1});
    s[n-1].S=0;
    while(!pq.empty()){
        temp=pq.top();
        pq.pop();
        if(went[temp.S])continue;
        went[temp.S]=true;
        for(pi i:graph[temp.S])if(!went[i.F]&&s[temp.S].S+i.S<s[i.F].S){
            s[i.F].S=s[temp.S].S+i.S;
            pq.push({s[i.F].S,i.F});
        }
    }
    sort(s,s+n);
    scanf("%d",&q);
    for(int i=0;i<q;i++){
        scanf("%lld%lld",&ask[i].F.F,&ask[i].F.S);
        ask[i].S=i;
    }
    sort(ask,ask+q);
    a=0;
    for(int i=0;i<q;i++){
        while(a<n){
            if(s[a].F<=ask[i].F.F){
                split(root,s[a].S,l,r);
                root=merge(l,new node(s[a].S));
                root=merge(root,r);
                a++;
            }
            else break;
        }
        ans[ask[i].S]=query(root,ask[i].F.S);
    }
    for(int i=0;i<q;i++)printf("%d\n",ans[i]);
}
accuracy: 1
time_ms: 150
memory_kb: 17760
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

struct SegTree{
    int n; vector<int> dat;
    //初期化
    SegTree(int _n){
        n=1;
        while(n<_n) n*=2;
        dat=vector<int>(2*n-1,0);
    }

    void add(int k, int a){
        k+=n-1;
        dat[k] += a;
        //更新
        while(k>0){
            k=(k-1)/2;
            dat[k]=dat[2*k+1]+dat[2*k+2];
        }
    }
    //内部的に投げられるクエリ
    int _query(int a, int b, int k, int l, int r){
        if(r<=a || b<=l) return 0;

        if(a<=l && r<=b) return dat[k];

        int vl=_query(a,b,2*k+1,l,(l+r)/2);
        int vr=_query(a,b,2*k+2,(l+r)/2,r);
        return vl+vr;
    }
    //[a,b)
    int query(int a, int b){
        return _query(a,b,0,0,n);
    }
};

const int N = 100000;
const ll INF = LLONG_MAX/3;

struct edge{ int to,cost; };
vector<edge> G[N];

int main(){
    int n,m;
    scanf(" %d %d", &n, &m);
    rep(i,m){
        int a,b,c;
        scanf(" %d %d %d", &a, &b, &c);
        G[a].pb({b,c});
        G[b].pb({a,c});
    }

    auto dijkstra = [&](int start){
        using P = pair<ll,int>;
        vector<ll> d(n,INF);
        priority_queue<P, vector<P>, greater<P>>pq;
        d[start] = 0;
        pq.push({0,start});
        while(!pq.empty()){
            P now = pq.top();
            pq.pop();
            int v = now.se;
            if(now.fi > d[v]) continue;
            for(const auto &e:G[v]){
                if(d[e.to] > d[v]+e.cost){
                    d[e.to] = d[v]+e.cost;
                    pq.push({d[e.to], e.to});
                }
            }
        }
        return d;
    };

    vector<ll> s = dijkstra(0), g = dijkstra(n-1);

    using pl = pair<ll,ll>;
    using query = pair<pl,int>;

    vector<ll> ug;

    int Q;
    scanf(" %d", &Q);
    vector<query> q(Q);
    rep(i,Q){
        ll fs,fg;
        scanf(" %lld %lld", &fs, &fg);
        q[i] = {{fs,fg}, i};
        ug.pb(fg);
    }
    sort(all(q));

    vector<pl> v(n);
    rep(i,n){
        v[i] = {s[i],g[i]};
        ug.pb(g[i]);
    }
    sort(all(v));

    sort(all(ug));
    ug.erase(unique(all(ug)), ug.end());
    int UG = ug.size();

    SegTree st(UG);

    int idx = 0;
    vector<int> ans(Q);
    rep(i,Q){
        int ID = q[i].se;
        ll fs = q[i].fi.fi, fg = q[i].fi.se;

        while(idx<n && v[idx].fi<=fs){
            int a_idx = lower_bound(all(ug), v[idx].se)-ug.begin();
            st.add(a_idx, 1);
            ++idx;
        }

        int gidx = lower_bound(all(ug), fg)-ug.begin();
        ans[ID] = st.query(gidx, UG);
    }

    rep(i,Q) printf("%d\n", ans[i]);
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 18388
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

struct SegTree{
    int n; vector<ll> dat;
    //初期化
    SegTree(int _n){
        n=1;
        while(n<_n) n*=2;
        dat=vector<ll>(2*n-1,0);
    }
    //k番目(0-indexed)の値をaに変更
    void add(int k, ll a){
        k+=n-1;
        dat[k] += a;
        //更新
        while(k>0){
            k=(k-1)/2;
            dat[k]=dat[2*k+1]+dat[2*k+2];
        }
    }
    //内部的に投げられるクエリ
    ll _query(int a, int b, int k, int l, int r){
        if(r<=a || b<=l) return 0;

        if(a<=l && r<=b) return dat[k];

        ll vl=_query(a,b,2*k+1,l,(l+r)/2);
        ll vr=_query(a,b,2*k+2,(l+r)/2,r);
        return vl+vr;
    }
    //[a,b)
    ll query(int a, int b){
        return _query(a,b,0,0,n);
    }
};

const int N = 100000;
const ll INF = LLONG_MAX/3;

struct edge{ int to,cost; };
vector<edge> G[N];

int main(){
    int n,m;
    scanf(" %d %d", &n, &m);
    rep(i,m){
        int a,b,c;
        scanf(" %d %d %d", &a, &b, &c);
        G[a].pb({b,c});
        G[b].pb({a,c});
    }

    auto dijkstra = [&](int start){
        using P = pair<ll,int>;
        vector<ll> d(n,INF);
        priority_queue<P, vector<P>, greater<P>>pq;
        d[start] = 0;
        pq.push({0,start});
        while(!pq.empty()){
            P now = pq.top();
            pq.pop();
            int v = now.se;
            if(now.fi > d[v]) continue;
            for(const auto &e:G[v]){
                if(d[e.to] > d[v]+e.cost){
                    d[e.to] = d[v]+e.cost;
                    pq.push({d[e.to], e.to});
                }
            }
        }
        return d;
    };

    vector<ll> s = dijkstra(0), g = dijkstra(n-1);

    using pl = pair<ll,ll>;
    using query = pair<pl,int>;

    vector<ll> ug;

    int Q;
    scanf(" %d", &Q);
    vector<query> q(Q);
    rep(i,Q){
        ll fs,fg;
        scanf(" %lld %lld", &fs, &fg);
        q[i] = {{fs,fg}, i};
        ug.pb(fg);
    }
    sort(all(q));

    vector<pl> v(n);
    rep(i,n){
        v[i] = {s[i],g[i]};
        ug.pb(g[i]);
    }
    sort(all(v));

    sort(all(ug));
    ug.erase(unique(all(ug)), ug.end());
    int UG = ug.size();

    SegTree st(UG);

    int idx = 0;
    vector<int> ans(Q);
    rep(i,Q){
        int ID = q[i].se;
        ll fs = q[i].fi.fi, fg = q[i].fi.se;

        while(idx<n && v[idx].fi<=fs){
            int a_idx = lower_bound(all(ug), v[idx].se)-ug.begin();
            st.add(a_idx, 1);
            ++idx;
        }

        int gidx = lower_bound(all(ug), fg)-ug.begin();
        ans[ID] = st.query(gidx, UG);
    }

    rep(i,Q) printf("%d\n", ans[i]);
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 20400
final_rank: 2

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>
#define llint long long
#define inf (1LL<<62)

using namespace std;
typedef pair<llint, llint> P;

struct edge{
	llint to, cost;
	edge(){}
	edge(llint a, llint b){
		to = a, cost = b;
	}
};

llint n, m, q;
vector<edge> G[100005];
llint distS[100005], distG[100005];
vector<llint> dvec;
vector<llint> compS, compG;
vector<llint> point[100005];
pair<P, llint> query[100005];
vector<P> qpoint[100005];
llint ans[100005];

llint bit[100005];
llint sum(llint i)
{
	i++;
	llint ret = 0;
	while(i > 0){
		ret += bit[i];
		i -= i & (-i);
	}
	return ret;
}
void add(llint i, llint x)
{
	i++;
	while(i <= n){
		bit[i] += x;
		i += i & (-i);
	}
}

llint get(llint x)
{
	return upper_bound(dvec.begin(), dvec.end(), x) - dvec.begin();
}

void dijkstra(llint S, llint dist[])
{
	for(int i = 0; i < n; i++) dist[i] = inf;
	dist[S] = 0;
	priority_queue< P, vector<P>, greater<P> > Q;
	Q.push(make_pair(0, S));
	
	llint d, v;
	while(Q.size()){
		d = Q.top().first;
		v = Q.top().second;
		Q.pop();
		if(dist[v] < d) continue;
		for(int i = 0; i < G[v].size(); i++){
			if(dist[G[v][i].to] > d + G[v][i].cost){
				dist[G[v][i].to] = d + G[v][i].cost;
				Q.push(make_pair(dist[G[v][i].to], G[v][i].to));
			}
		}
	}
}

int main(void)
{
	cin >> n >> m;
	llint a, b, c;
	for(int i = 0; i < m; i++){
		cin >> a >> b >> c;
		G[a].push_back(edge(b, c));
		G[b].push_back(edge(a, c));
	}
	
	dijkstra(0, distS);
	dijkstra(n-1, distG);
	
	for(int i = 0; i < n; i++) dvec.push_back(distS[i]);
	sort(dvec.begin(), dvec.end());
	
	
	for(int i = 0; i < n; i++) compS.push_back(distS[i]);
	sort(compS.begin(), compS.end());
	compS.erase(unique(compS.begin(), compS.end()), compS.end());
	for(int i = 0; i < n; i++){
		distS[i] = lower_bound(compS.begin(), compS.end(), distS[i]) - compS.begin();
	}
	
	for(int i = 0; i < n; i++) compG.push_back(distG[i]);
	sort(compG.begin(), compG.end());
	compG.erase(unique(compG.begin(), compG.end()), compG.end());
	for(int i = 0; i < n; i++){
		distG[i] = lower_bound(compG.begin(), compG.end(), distG[i]) - compG.begin();
	}
	
	for(int i = 0; i < n; i++) point[distG[i]].push_back(distS[i]);
	
	
	llint q;
	cin >> q;
	for(int i = 0; i < q; i++){
		cin >> query[i].first.first >> query[i].first.second;
		query[i].first.second--;
		query[i].second = i;
	}
	for(int i = 0; i < q; i++){
		query[i].first.first = upper_bound(compS.begin(), compS.end(), query[i].first.first) - 1 - compS.begin();
		query[i].first.second = upper_bound(compG.begin(), compG.end(), query[i].first.second) - 1 - compG.begin();
	}
	
	for(int i = 0; i < q; i++){
		if(query[i].first.first >= 0){
			qpoint[query[i].first.second].push_back(make_pair(query[i].first.first, query[i].second));
		}
	}
	
	for(int i = 0; i < q; i++){
		if(query[i].first.second < 0){
			ans[query[i].second] = get(compS[query[i].first.first]);
		}
	}
	for(int i = 0; i <= compG.size(); i++){
		for(int j = 0; j < point[i].size(); j++) add(point[i][j], 1);
		for(int j = 0; j < qpoint[i].size(); j++){
			ans[qpoint[i][j].second] = get(compS[query[qpoint[i][j].second].first.first]) - sum(qpoint[i][j].first);
		}
	}
	for(int i = 0; i < q; i++) cout << ans[i] << endl;
	
	return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 28148
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) (v).begin(), (v).end()
#define resz(v, ...) (v).clear(), (v).resize(__VA_ARGS__)
#define reps(i, m, n) for(int i = (int)(m); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)

template<class T1, class T2> void chmin(T1 &a, T2 b){if(a>b)a=b;}
template<class T1, class T2> void chmax(T1 &a, T2 b){if(a<b)a=b;}

using Pi = pair<int, int>;
using Tapris = tuple<int, int, int>;
using vint = vector<int>;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  const int sqrtN = 512;

  int n, m;
  cin >> n >> m;

  struct edge {
    int to, cost;
    edge(){}
    edge(int to, int cost):to(to), cost(cost){}
  };
  vector<vector<edge> > graph(n);
  rep(i, m) {
    int a, b, c;
    cin >> a >> b >> c;
    graph[a].emplace_back(b, c);
    graph[b].emplace_back(a, c);
  }

  auto dijkstra = [&](int s){
    vint res(n, inf);
    res[s] = 0;
    priority_queue<Pi, vector<Pi>, greater<Pi> > que;
    que.emplace(res[s], s);
    while(!que.empty()) {
      Pi p = que.top(); que.pop();
      int v = p.second;
      if(res[v] < p.first) continue;
      for(edge& e : graph[v]) {
	if(e.cost+res[v] < res[e.to]) {
	  res[e.to] = e.cost+res[v];
	  que.emplace(res[e.to], e.to);
	}
      }
    }
    return res;
  };

  auto ds = dijkstra(0);
  auto dg = dijkstra(n-1);

  vint press_ds;
  rep(i, n) press_ds.push_back(ds[i]);

  int q;
  cin >> q;
  vector<Pi> qs;
  rep(i, q) {
    int f, g;
    cin >> f >> g;
    qs.emplace_back(f, g);
    press_ds.push_back(f);
  }

  sort(all(press_ds));
  press_ds.erase(unique(all(press_ds)), press_ds.end());

  int bucket_sz = ((int)press_ds.size()+sqrtN-1)/sqrtN;
  vector<vector<int> > bucket_dat(bucket_sz);
  vector<vector<int> > dat(press_ds.size());
  rep(i, n) {
    int p = lower_bound(all(press_ds), ds[i])-press_ds.begin();
    bucket_dat[p/sqrtN].push_back(dg[i]);
    dat[p].push_back(dg[i]);
  }

  rep(i, bucket_sz) sort(all(bucket_dat[i]));
  rep(i, dat.size()) sort(all(dat[i]));

  auto ask = [&](int a, int b, int x) {
    int res = 0;
    rep(i, bucket_sz) {
      int l = i*sqrtN, r = (i+1)*sqrtN;
      if(r <= a || b <= l) continue;
      if(a <= l && r <= b) {
	res += bucket_dat[i].end() - lower_bound(all(bucket_dat[i]), x);
      } else {
	reps(j, max(a, l), min(b, r)) {
	  res += dat[j].end() - lower_bound(all(dat[j]), x);
	}
      }
    }
    return res;
  };

  for(Pi p : qs) {
    int l = 0, r = upper_bound(all(press_ds), p.first)-press_ds.begin();
    cout << ask(l, r, p.second) << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 750
memory_kb: 22552
final_rank: 11