zoukankan      html  css  js  c++  java
  • BZOJ 4129 Haruna’s Breakfast ( 树上带修莫队 )

    题面

    求树上某路径上最小的没出现过的权值,有单点修改 添加链接描述

    分析

    树上带修莫队板题,问题是怎么求最小的没出现过的权值。
    因为只有nn个点,所以没出现过的最小值一定在[0,n][0,n]内,所以大于nn的无需维护。那么我们就值域分块,每nsqrt n个数开一个数组,那么从小到大枚举块,如果当前块没有满那么就在这个块里查找,每次查找时间复杂度为O(n)O(sqrt n)。因为n,mn,m值域相同,所以总时间复杂度为O(n53()+nn()+nlogn())O(n^{frac 53}(莫队)+nsqrt n(分块查 询)+nlogn(排序))

    • 我用的是倍增求LCA

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    template<typename T>inline void read(T &num) {
       char ch; while((ch=getchar())<'0'||ch>'9');
       for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
    }
    const int MAXN = 50005;
    int n, m, TreeB, ValB, TIMES, cntq, cntc;
    int a[MAXN], la[MAXN], bel[MAXN], ans[MAXN];
    struct QUERY {
       int u, v, t, id;
       inline bool operator <(const QUERY &o)const {
       	return bel[u] == bel[o.u] ? (bel[v] == bel[o.v] ? t < o.t : bel[v] < bel[o.v]) : bel[u] < bel[o.u];
       }
    }Q[MAXN];
    struct CHANGE { int i, u, v; }C[MAXN];
    int fir[MAXN], to[MAXN<<1], nxt[MAXN<<1], cnt;
    inline void add(int u, int v) { to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; }
    int stk[MAXN], f[MAXN][16], dep[MAXN], dfn[MAXN], tmr, tot, top;
    
    inline void dfs(int u, int ff) {
       int bot = top; dfn[u] = ++tmr;
       dep[u] = dep[f[u][0]=ff] + 1;
       for(int i = fir[u]; i; i = nxt[i])
       	if(to[i] != ff) {
       		dfs(to[i], u);
       		if(top-bot > TreeB) {
       			++tot;
       			while(top > bot) bel[stk[top--]] = tot;
       		}
       	}
       stk[++top] = u;
    }
    
    inline void Pre() {
       for(int j = 1; j < 16; ++j)
       	for(int i = 1; i <= n; ++i)
       		f[i][j] = f[f[i][j-1]][j-1];
    }
    
    bool vis[MAXN]; int sz[MAXN], val[MAXN];
    
    inline int lca(int u, int v) {
       if(dep[u] < dep[v]) swap(u, v);
       for(int j = 0; j < 16; ++j)
       	if((dep[u]-dep[v])&(1<<j)) u = f[u][j]; 
       if(u == v) return u;
       for(int j = 15; ~j; --j)
       	if(f[u][j] != f[v][j]) u = f[u][j], v = f[v][j];
       return f[u][0];
    }
    
    inline void upd(int i) {
       if(!vis[i]) {
       	vis[i] = 1; if(a[i] > n) return;
       	if(++val[a[i]] == 1) ++sz[a[i]/ValB];
       }
       else {
       	vis[i] = 0; if(a[i] > n) return;
       	if(--val[a[i]] == 0) --sz[a[i]/ValB];
       }
    }
    
    inline void rev(int u, int v) {
       while(u != v) {
       	if(dep[u] < dep[v]) swap(u, v);
       	upd(u), u = f[u][0];
       }
    }
    inline void modify(int i, int col) {
       if(!vis[i]) { a[i] = col; return; }
       upd(i), a[i] = col, upd(i);
    }
    inline int solve() {
       for(int i = 0; ; ++i) if(sz[i] != ValB)
       	for(int j = i*ValB; ; ++j) if(!val[j])
       		return j;
    }
    
    int main () {
       read(n), read(m), TreeB = int(pow(n, 0.67)), ValB = int(sqrt(1.0*n));
       for(int i = 1; i <= n; ++i) read(a[i]), la[i] = a[i];
       for(int i = 1, u, v; i < n; ++i) read(u), read(v), add(u, v), add(v, u);
       for(int i = 1, opt, x, y; i <= m; ++i) {
       	read(opt), read(x), read(y);
       	if(!opt) C[++cntc] = (CHANGE){ x, la[x], y }, la[x] = y;
       	else {
       		if(dfn[x] > dfn[y]) swap(x, y);
       		Q[++cntq] = (QUERY){ x, y, cntc, cntq };
       	}
       }
       dfs(1, 0); if(top) ++tot; while(top) bel[stk[top--]] = tot; Pre();
       sort(Q + 1, Q + cntq + 1);
       while(TIMES < Q[1].t) ++TIMES, modify(C[TIMES].i, C[TIMES].v);
       rev(Q[1].u, Q[1].v); int LCA = lca(Q[1].u, Q[1].v);
       upd(LCA), ans[Q[1].id] = solve(), upd(LCA);
       for(int i = 2; i <= cntq; ++i) {
       	while(TIMES < Q[i].t) ++TIMES, modify(C[TIMES].i, C[TIMES].v);
       	while(TIMES > Q[i].t) modify(C[TIMES].i, C[TIMES].u), --TIMES;
       	rev(Q[i-1].u, Q[i].u), rev(Q[i-1].v, Q[i].v), LCA = lca(Q[i].u, Q[i].v);
       	upd(LCA), ans[Q[i].id] = solve(), upd(LCA);
       }
       for(int i = 1; i <= cntq; ++i)
       	printf("%d
    ", ans[i]);
       return 0;
    }
    
  • 相关阅读:
    团队作业2
    团队作业2
    软件工程-团队作业1
    软件工程第一次作业
    自我介绍
    软件工程第一次作业
    Python3中采用PyInstaller打包工程项目
    mol2分子库文件拆分成单个mol2文件
    化学信息包安装
    单词读音音频源网址
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039424.html
Copyright © 2011-2022 走看看