洛谷 P3459 [POI2007]MEG-Megalopolis(dfs序+线段树)

Description:

Byteotia has been eventually touched by globalisation, and so has Byteasar the Postman, who once roamedthe country lanes amidst sleepy hamlets and who now dashes down the motorways. But it is those strolls inthe days of yore that he reminisces about with a touch of tenderness.

In the olden days nn Byteotian villages (numbered from 11 to nn) were connected by bidirectional dirt roadsin such a way, that one could reach the village number 11 (called Bitburg) from any other village in exactlyone way. This unique route passed only through villages with number less or equal to that of the startingvillage. Furthermore, each road connected exactly two distinct villages without passing through any othervillage. The roads did not intersect outside the villages, but tunnels and viaducts were not unheard of.

Time passing by, successive roads were being transformed into motorways. Byteasar remembers distinctly, when each of the country roads so disappeared. Nowadays, there is not a single country lane left in Byteotia - all of them have been replaced with motorways, which connect the villages into Byteotian Megalopolis.

Byteasar recalls his trips with post to those villages. Each time he was beginning his journey with letters to some distinct village in Bitburg. He asks you to calculate, for each such journey (which took place in a specific moment of time and led from Bitburg to a specified village), how many country roads it led through.

TaskWrite a programme which:

reads from the standard input:

descriptions of roads that once connected Byteotian villages, sequence of events: Byteasar’s trips and the moments when respective roads were transformed into motorways, for each trip, calculates how many country roads Byteasar has had to walk, writes the outcome to the standard output.

在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了。不过,她经常回忆起以前在乡间漫步的情景。昔日,乡下有依次编号为1…n的n个小村庄,某些村庄之间有一些双向的土路。从每个村庄都恰好有一条路径到达村庄1(即比特堡)。并且,对于每个村庄,它到比特堡的路径恰好只经过编号比它的编号小的村庄。另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇。在这个未开化的地方,从来没有过高架桥和地下铁道。随着时间的推移,越来越多的土路被改造成了公路。至今,Blue Mary还清晰地记得最后一条土路被改造为公路的情景。现在,这里已经没有土路了——所有的路都成为了公路,而昔日的村庄已经变成了一个大都市。 Blue Mary想起了在改造期间她送信的经历。她从比特堡出发,需要去某个村庄,并且在两次送信经历的间隔期间,有某些土路被改造成了公路.现在Blue Mary需要你的帮助:计算出每次送信她需要走过的土路数目。(对于公路,她可以骑摩托车;而对于土路,她就只好推车了。)

Input:

In the first line of the standard input there is a single integer n n n ( 1 n 250 <mtext>   </mtext> 000 1\le n\le 250\ 000 1n250 000 ),denoting the number of villages in Byteotia. The following n 1 n-1 n1 lines contain descriptions of the roads, in the form of two integers a a a , b b b ( 1 a &lt; b n 1\le a&lt;b\le n 1a<bn )separated by a single space, denoting the numbers of villages connected with a road. Inthe next line there is a single integer m m m ( 1 m 250 <mtext>   </mtext> 00 1\le m\le 250\ 00 1m250 00 ),denoting the number of trips Byteasar has made.

The following n + m 1 n+m-1 n+m1 lines contain descriptions of the events, in chronological order:

A description of the form "A a a a b b b "(for a &lt; b a&lt;b a<b ) denotes a country road between villages aa and bbbeingtransformed into a motorway in that particular moment.

A description of the from "W a a a " denotes Byteasar’s trip from Bitburg to village a a a .

Output:

Your programme should write out exactly mm integers to the standard output, one a line, denoting the numberof country roads Byteasar has travelled during his successive trips.

Sample Input:

5
1 2
1 3
1 4
4 5
4
W 5
A 1 4
W 5
A 4 5
W 5
W 2
A 1 2
A 1 3

Sample Output:

2
1
0
1

题目链接

给定一棵N个点的树,每条边边权均为1,共N+M-1次操作

  1. 把一条边边权从1变为0
  2. 询问根节点到一个点所经过的边的权和

用线段树在 d f s dfs dfs 序上维护每个节点到根节点的距离

AC代码:

// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 5;

vector<vector<int>> g;

vector<int> in, out;
vector<int> dep;
vector<int> order;

void DfsOrder(int cur, int prev) {
  in[cur] = order.size();
  order.emplace_back(cur);
  for (auto &it : g[cur]) {
    if (it == prev) continue;
    dep[it] = dep[cur] + 1;
    DfsOrder(it, cur);
  }
  out[cur] = order.size() - 1;
}

class seg_tree {
  public:
    typedef int type_t;
    struct node {
      type_t v, lazy;
      node(type_t _v = 0, type_t _lazy = 0): v(_v), lazy(_lazy) {}
    };

    node Unite(const node &k1, const node &k2) {
      node ans;
      ans.v = k1.v + k2.v;
      return ans;
    }

    void Pull(int o) {
      tree[o] = Unite(tree[o << 1], tree[o << 1 | 1]);
    }

    void Push(int o, int l, int r) {
      int m = (l + r) >> 1;
      if (tree[o].lazy != 0) {
        tree[o << 1].v += (m - l + 1) * tree[o].lazy;
        tree[o << 1 | 1].v += (r - m) * tree[o].lazy;
        tree[o << 1].lazy += tree[o].lazy;
        tree[o << 1 | 1].lazy += tree[o].lazy;
        tree[o].lazy = 0;
      }
    }

    int n;
    vector<node> tree;

    void Build(int o, int l, int r, const vector<type_t> &v) {
      if (l == r) {
        tree[o].v = v[l - 1];
        return;
      }
      int m = (l + r) >> 1;
      Build(o << 1, l, m, v);
      Build(o << 1 | 1, m + 1, r, v);
      Pull(o);
    }

    seg_tree(const vector<type_t> &v) {
      n = v.size();
      tree.resize(n << 2);
      Build(1, 1, n, v);
    }

    void Modify(int o, int l, int r, int ll, int rr, type_t v) {
      if (ll <= l && rr >= r) {
        tree[o].v += (r - l + 1) * v;
        tree[o].lazy += v;
        return;
      }
      Push(o, l, r);
      int m = (l + r) >> 1;
      if (ll <= m) Modify(o << 1, l, m, ll, rr, v);
      if (rr > m) Modify(o << 1 | 1, m + 1, r, ll, rr, v);
      Pull(o);
    }
    void Modify(int ll, int rr) {
      Modify(1, 1, n, ll, rr, -1);
    }

    node Query(int o, int l, int r, int ll, int rr) {
      if (ll <= l && rr >= r) return tree[o];
      Push(o, l, r);
      int m = (l + r) >> 1;
      if (ll <= m) return Query(o << 1, l, m, ll, rr);
      if (rr > m) return Query(o << 1 | 1, m + 1, r, ll, rr);
      Pull(o);
    }
    node Query(int ll, int rr) {
      return Query(1, 1, n, ll, rr);
    }
};

int main() {
  ios::sync_with_stdio(false); cin.tie(0);
  int n; cin >> n;
  g.resize(n);
  for (int i = 1, u, v; i < n; ++i) {
    cin >> u >> v;
    --u; --v;
    g[u].emplace_back(v);
    g[v].emplace_back(u);
  }
  in.resize(n); out.resize(n);
  dep.assign(n, 0);
  DfsOrder(0, -1);
  for (int i = 0; i < order.size(); ++i) order[i] = dep[order[i]];
  seg_tree sgt(order);
  int m; cin >> m;
  m = n + m - 1;
  for (int i = 0, u, v; i < m; ++i) {
    char op; cin >> op;
    if (op == 'W') {
      cin >> u;
      --u;
      cout << sgt.Query(in[u] + 1, in[u] + 1).v << endl;
    }
    else if (op == 'A') {
      cin >> u >> v;
      --u; --v;
      if (dep[u] < dep[v]) swap(u, v);
      sgt.Modify(in[u] + 1, out[u] + 1);
    }
  }
  return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务