zoukankan      html  css  js  c++  java
  • [BZOJ4763][P3603]雪辉[手写bitset+静态分块]

    题意:给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex
    mex就是一个集合中最小的没有出现的非负整数,注意0要算

    rand出 (sqrt n)个点,把每次查询拆成 x->fx0->fx->lca->fy->fy0->y

    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    template<typename T> void read(T & x) {
      int c = getchar(); x = 0;
      while(!isdigit(c)) c = getchar();
      while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
    }
    #define read2(a, b) (read(a), read(b))
    #define read3(a, b, c) (read(a), read2(b, c))
    const int MAXN = 100007;
    struct Edge{
      int v, next;
    }G[MAXN<<1]; int tot, head[MAXN], dq[MAXN], n, q, siz[MAXN], dep[MAXN], top[MAXN], anc[MAXN], son[MAXN], cnt[1<<16], s, m, u, v, up[MAXN], pos[357], lca, b, tpos[MAXN];
    bool vis[MAXN], f;
    int _popcount(int x) {
      static int ret;
      for(ret = 0; x; ret += x & 1, x >>= 1);
      return ret;
    }
    int popcount(ull x) {
      static int ret = 0;
      for(ret = 0; x; ret += cnt[x & 0xffff], x >>= 16);
      return ret;
    }
    inline void chmax(int &x, int y) {if (x < y) x = y;}
    struct Bitset{
      static const ull ful = 0xffffffffffffffff;
      ull bit[470]; int len, Mex, Num;
      void reset() {for(int i = 0; i <= len; ++i) bit[i] = 0; len = 0; Num = Mex = 0;}
      void operator |= (const Bitset &rhs) {
        chmax(len, rhs.len);
        for(int i = 0; i <= len; ++i) bit[i] |= rhs.bit[i];
      }
      void operator |= (int x) {
        chmax(len, x >> 6);
        bit[x >> 6] |= 1ull << (x & 63);
      }
      int mex() {
        for(int i = 0; i <= len; ++i) 
          if (bit[i] != ful) 
            for(int j = 0; j < 64; ++j) if (!(bit[i] & (1ull<<j))) return Mex = i * 64 + j;
      }
      int num() {
        for(int i = 0; i <= len; ++i) 
          Num += popcount(bit[i]);
        return Num;
      }
    }dis[353][351], t; 
      
    void add(int u, int v) {G[++tot] = (Edge){v, head[u]}; head[u] = tot;}
    #define v G[i].v
    void dfs1(int u) {
      dep[u] = dep[anc[u]] + 1;
      siz[u] = 1;
      for(int i = head[u]; i; i = G[i].next) {
        if (v == anc[u]) continue;
        anc[v] = u;
        dfs1(v), siz[u] += siz[v];
        if (siz[son[u]] <= siz[v]) son[u] = v;
      }
    }
    void dfs2(int u, int t) {
      top[u] = t;
      if (son[u]) dfs2(son[u], t);
      for(int i = head[u]; i; i = G[i].next) 
        if (v != son[u] && v != anc[u]) dfs2(v, v);
    }
    #undef v
    int LCA(int u, int v) {
      while(top[u] != top[v]) 
        dep[top[u]] >= dep[top[v]] ? u = anc[top[u]] : v = anc[top[v]];
      return dep[u] < dep[v] ? u : v;
    }
    #define u1(x) while(!vis[x] && x != lca) t |= dq[x], x = anc[x];
    #define u3(x) while(x != lca) t |= dq[x], x = anc[x];
    void u2(int &x) {
      int nx = x;
      while(dep[up[x]] > dep[lca]) x = up[x];
      t |= dis[tpos[nx]][tpos[x]];
    }
    void update() {
      u1(u); u1(v);
      u2(u); u2(v);
      u3(u); u3(v);
    }
    int main(void) {
    //  freopen("data.in", "r", stdin);
      for(int i = 0; i < (1<<16); ++i) cnt[i] = _popcount(i);
      read3(n, m, f);
      for(int i = 1; i <= n; ++i) read(dq[i]);
      for(int i = 1; i < n; ++i) read2(u, v), add(u, v), add(v, u);
      dfs1(1);
      dfs2(1, 1);
      s = sqrt(n);
      for(int i = 1; i <= s; ++i) {
        do q = rand()%n+1;while(vis[q]);
        vis[q] = 1, tpos[pos[i] = q] = i;
      }
      for(int i = 1; i <= s; ++i) {
        int u = pos[i]; t.reset();
        while(u){
          t |= dq[u];
          if (vis[u] && u != pos[i]) {
            dis[i][tpos[u]] |= t;
            if (!up[pos[i]]) up[pos[i]] = u;
          }
          u = anc[u];
        }
      }
      int last = 0;
      while(m--) {
        t.reset(); read(b);
        while(b--) {
          read2(u, v); 
          if (f) u ^= last, v ^= last;
          lca = LCA(u, v), t |= dq[lca];
          update();
        }
        last = t.num()+t.mex();
        printf("%d %d
    ", t.Num, t.Mex);
      }
      return 0;
    }
    
  • 相关阅读:
    SqlLite的使用
    asp.net批量上传图片带进度条显示
    对于GridView控件的RowDataBount事件的错误理解
    关于SQL中时间对比
    关于使用触发器时使用@@identity的问题
    关于Treeview控件如何给每个节点加js脚本的方法
    /etc/init.d/functions详解
    如何解决安装DreamWeaver8 时候提示“无法将数值写入键/SOFTWARE/classes/.shtml”
    [请教]关于超大数据量网站的数据搜索和分页的实现方法
    svchost.exe[900]中发生未处理的win32异常
  • 原文地址:https://www.cnblogs.com/storz/p/10191275.html
Copyright © 2011-2022 走看看