zoukankan      html  css  js  c++  java
  • Count on a tree II [树分块]

    bzoj2589
    大概是选几个关键点,然后跳来跳去就好了。
    b[40][40] 表示一条链上跳的QwQ

    // powered by c++11
    // by Isaunoya
    #include <bits/stdc++.h>
    #define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
    #define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
    using namespace std;
    using db = double;
    using ll = long long;
    using uint = unsigned int;
    #define Tp template
    using pii = pair<int, int>;
    #define fir first
    #define sec second
    Tp<class T> void cmax(T& x, const T& y) {
      if (x < y) x = y;
    }
    Tp<class T> void cmin(T& x, const T& y) {
      if (x > y) x = y;
    }
    #define all(v) v.begin(), v.end()
    #define sz(v) ((int)v.size())
    #define pb emplace_back
    Tp<class T> void sort(vector<T>& v) { sort(all(v)); }
    Tp<class T> void reverse(vector<T>& v) { reverse(all(v)); }
    Tp<class T> void unique(vector<T>& v) { sort(all(v)), v.erase(unique(all(v)), v.end()); }
    const int SZ = 1 << 23 | 233;
    struct FILEIN {
      char qwq[SZ], *S = qwq, *T = qwq, ch;
    #ifdef __WIN64
    #define GETC getchar
    #else
      char GETC() { return (S == T) && (T = (S = qwq) + fread(qwq, 1, SZ, stdin), S == T) ? EOF : *S++; }
    #endif
      Tp<class T> void read(T& x) {
        bool sign = 0;
        while ((ch = GETC()) < 48) sign ^= (ch == 45);
        x = (ch ^ 48);
        while ((ch = GETC()) > 47) x = (x << 1) + (x << 3) + (ch ^ 48);
        x = sign ? -x : x;
      }
      FILEIN& operator>>(int& x) { return read(x), *this; }
    } in;
    struct FILEOUT {
      const static int LIMIT = 1 << 22;
      char quq[SZ], ST[233];
      int sz, O;
      ~FILEOUT() { flush(); }
      void flush() {
        fwrite(quq, 1, O, stdout);
        fflush(stdout);
        O = 0;
      }
      FILEOUT& operator<<(char c) { return quq[O++] = c, *this; }
      Tp<class T> void write(T x) {
        if (O > LIMIT) flush();
        if (x < 0) {
          quq[O++] = 45;
          x = -x;
        }
        do {
          ST[++sz] = x % 10 ^ 48;
          x /= 10;
        } while (x);
        while (sz) quq[O++] = ST[sz--];
      }
      FILEOUT& operator<<(int x) { return write(x), *this; }
    } out;
    
    int n, m;
    const int maxn = 4e4 + 2;
    bitset<maxn> qwq[42][42], qaq;
    vector<int> g[maxn];
    int a[maxn], b[maxn], sz[maxn], son[maxn], mxd[maxn], dep[maxn], fa[maxn];
    int id[maxn], cnt = 0;
    
    void dfs(int u) {
      sz[u] = 1, mxd[u] = dep[u];
      for (int v : g[u])
        if (!dep[v]) {
          dep[v] = dep[u] + 1, fa[v] = u;
          dfs(v), sz[u] += sz[v];
          cmax(mxd[u], mxd[v]);
          if (sz[v] > sz[son[u]]) son[u] = v;
        }
      if (mxd[u] - dep[u] >= 1000) id[u] = ++cnt, mxd[u] = dep[u];
    }
    
    int ff[maxn], st[maxn], top = 0;
    
    void dfs2(int u) {
      for (int v : g[u])
        if (dep[v] > dep[u]) {
          if (id[v]) {
            int ip = id[st[top]], in = id[v];
            for (int x = v; x != st[top]; x = fa[x]) qwq[ip][in].set(a[x]);
            qaq = qwq[ip][in];
            for (int i = 1; i < top; i++) {
            	qwq[id[st[i]]][in] = qwq[id[st[i]]][ip];
    					qwq[id[st[i]]][in] |= qaq;
    				}
            ff[v] = st[top], st[++top] = v;
          }
          dfs2(v);
          if (id[v]) --top;
        }
    }
    
    int tp[maxn];
    void dfs3(int u, int t) {
      tp[u] = t;
      if (son[u]) dfs3(son[u], t);
      for (int v : g[u])
        if (!tp[v]) dfs3(v, v);
    }
    
    int lca(int x, int y) {
      while (tp[x] != tp[y]) (dep[tp[x]] > dep[tp[y]]) ? x = fa[tp[x]] : y = fa[tp[y]];
      return dep[x] < dep[y] ? x : y;
    }
    
    void qwqwq(int x, int lca) {
      while (x != lca && !id[x]) qaq.set(a[x]), x = fa[x];
      if (x != lca) {
        int pre = x;
        while (dep[ff[pre]] >= dep[lca]) pre = ff[pre];
        if (pre != x) qaq |= qwq[id[pre]][id[x]];
        while (pre != lca) qaq.set(a[pre]), pre = fa[pre];
      }
    }
    
    int qry(int x, int y) {
      int Lca = lca(x, y);
      qaq.reset(), qaq.set(a[Lca]);
      qwqwq(x, Lca), qwqwq(y, Lca);
      return qaq.count();
    }
    
    signed main() {
      // code begin.
      in >> n >> m;
      rep(i, 1, n) in >> a[i], b[i] = a[i];
      sort(b + 1, b + n + 1);
      int len = unique(b + 1, b + n + 1) - b - 1;
      rep(i, 1, n) a[i] = lower_bound(b + 1, b + len + 1, a[i]) - b;
      rep(i, 2, n) {
        int u, v;
        in >> u >> v, g[u].pb(v), g[v].pb(u);
      }
      dfs(dep[1] = 1);
      if (!id[1]) id[1] = ++cnt;
      st[++top] = 1, dfs2(1), dfs3(1, 1);
      int ans = 0;
      while (m--) {
        int u, v;
        in >> u >> v, u ^= ans;
        out << (ans = qry(u, v)) << '
    ';
      }
      return 0;
      // code end.
    }
    
  • 相关阅读:
    EBS SQL > Form & Report
    oracle sql 优化分析点
    MRP 物料需求计划
    MRPII 制造资源计划
    Barcode128 应用实务
    Oracle SQL语句优化技术分析
    APPSQLAP10710 Online accounting could not be created. AP Invoice 无法创建会计分录
    Oracle数据完整性和锁机制
    ORACLE Responsibility Menu Reference to Other User
    EBS 常用 SQL
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12445910.html
Copyright © 2011-2022 走看看