• [洛谷P3613]睡觉困难综合征


    题目大意:[NOI2014]起床困难综合症加强版,出到树上,$m(mleqslant10^5)$组询问,带修改,数的范围$<2^{64})$

    题解:先想到树剖,转化为序列问题,线段树维护区间从左到右和从右到左$01$变化值,然后发现如果对每一位考虑,复杂度为$O(64nlog_2^2n)$,$0.5s$时限并过不去。考虑去掉$k$,可以使用位运算来$O(1)$合并区间。

    注意树剖询问的时候要按顺序修改,不可以反过来。

    卡点:



    C++ Code:

    #include <algorithm>
    #include <cstdio>
    #include <cctype>
    namespace __IO {
    	int x, ch;
    	inline int read() {
    		while (isspace(ch = getchar())) ;
    		for (x = ch & 15; isdigit(ch = getchar()); ) x = x * 10 + (ch & 15);
    		return x;
    	}
    	unsigned long long X;
    	inline unsigned long long readllu() {
    		while (isspace(ch = getchar())) ;
    		for (X = ch & 15; isdigit(ch = getchar()); ) X = X * 10 + (ch & 15);
    		return X;
    	}
    }
    using __IO::read;
    using __IO::readllu;
    
    const int maxn = 100010;
    const unsigned long long inf = ~0;
    
    int Opt[maxn], __Opt[maxn];
    unsigned long long Num[maxn], __Num[maxn];
    int n, m, __p;
    inline void calc(unsigned long long &x, int y, unsigned long long z) {
    	switch (y) {
    		case 1: x &= z; break;
    		case 2: x |= z; break;
    		case 3: x ^= z;
    	}
    }
    struct node {
    	unsigned long long __0, __1;
    	inline friend node operator + (const node &lhs, const node &rhs) {
    		return (node) {
    			(lhs.__0 & rhs.__1) | (~lhs.__0 & rhs.__0),
    			(lhs.__1 & rhs.__1) | (~lhs.__1 & rhs.__0)
    		};
    	}
    } ;
    namespace SgT {
    	const int N = maxn << 2;
    	node lr[N], rl[N];
    
    	void build(const int rt, const int l, const int r) {
    		if (l == r) {
    			calc(lr[rt].__0 = 0, Opt[l], Num[l]);
    			calc(lr[rt].__1 = inf, Opt[l], Num[l]);
    			calc(rl[rt].__0 = 0, Opt[l], Num[l]);
    			calc(rl[rt].__1 = inf, Opt[l], Num[l]);
    			return ;
    		}
    		const int mid = l + r >> 1, lc = rt << 1, rc = rt << 1 | 1;
    		build(lc, l, mid), build(rc, mid + 1, r);
    		lr[rt] = lr[lc] + lr[rc];
    		rl[rt] = rl[rc] + rl[lc];
    	}
    
    	int pos;
    	void __modify(const int rt, const int l, const int r) {
    		if (l == r) {
    			calc(lr[rt].__0 = 0, Opt[l], Num[l]);
    			calc(lr[rt].__1 = inf, Opt[l], Num[l]);
    			calc(rl[rt].__0 = 0, Opt[l], Num[l]);
    			calc(rl[rt].__1 = inf, Opt[l], Num[l]);
    			return ;
    		}
    		const int mid = l + r >> 1, lc = rt << 1, rc = rt << 1 | 1;
    		if (pos <= mid) __modify(lc, l, mid);
    		else __modify(rc, mid + 1, r);
    		lr[rt] = lr[lc] + lr[rc];
    		rl[rt] = rl[rc] + rl[lc];
    	}
    	void modify(int __pos, int y, unsigned long long z) {
    		pos = __pos;
    		Opt[pos] = y;
    		Num[pos] = z;
    		__modify(1, 1, n);
    	}
    
    	int L, R;
    	node res;
    	void querylr(const int rt, const int l, const int r) {
    		if (L <= l && R >= r) {
    			res = res + lr[rt];
    			return ;
    		}
    		const int mid = l + r >> 1;
    		if (L <= mid) querylr(rt << 1, l, mid);
    		if (R > mid) querylr(rt << 1 | 1, mid + 1, r);
    	}
    	void queryrl(const int rt, const int l, const int r) {
    		if (L <= l && R >= r) {
    			res = res + rl[rt];
    			return ;
    		}
    		const int mid = l + r >> 1;
    		if (R > mid) queryrl(rt << 1 | 1, mid + 1, r);
    		if (L <= mid) queryrl(rt << 1, l, mid);
    	}
    	node query(int __L, int __R) {
    		res.__0 = 0, res.__1 = inf;
    		if (__L <= __R) {
    			L = __L, R = __R;
    			querylr(1, 1, n);
    		} else {
    			L = __R, R = __L;
    			queryrl(1, 1, n);
    		}
    		return res;
    	}
    }
    
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt;
    } e[maxn << 1];
    inline void addedge(int a, int b) {
    	e[++cnt] = (Edge) { b, head[a] }; head[a] = cnt;
    	e[++cnt] = (Edge) { a, head[b] }; head[b] = cnt;
    }
    
    int fa[maxn], dep[maxn], sz[maxn];
    int dfn[maxn], idx, top[maxn], son[maxn];
    void dfs1(int u) {
    	sz[u] = 1;
    	for (int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if (v != fa[u]) {
    			fa[v] = u;
    			dep[v] = dep[u] + 1;
    			dfs1(v);
    			if (!son[u] || sz[v] > sz[son[u]]) son[u] = v;
    			sz[u] += sz[v];
    		}
    	}
    }
    void dfs2(int u) {
    	dfn[u] = ++idx;
    	int v = son[u];
    	if (v) top[v] = top[u], dfs2(v);
    	for (int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if (v != fa[u] && v != son[u]) {
    			top[v] = v;
    			dfs2(v);
    		}
    	}
    }
    
    unsigned long long query(int x, int y, unsigned long long z) {
    	static node res, S[maxn];
    	int tot = 0;
    	res.__0 = 0, res.__1 = inf;
    	while (top[x] != top[y]) {
    		if (dep[top[x]] > dep[top[y]]) {
    			res = res + SgT::query(dfn[x], dfn[top[x]]);
    			x = fa[top[x]];
    		} else {
    			S[++tot] = SgT::query(dfn[top[y]], dfn[y]);
    			y = fa[top[y]];
    		}
    	}
    	res = res + SgT::query(dfn[x], dfn[y]);
    	while (tot) res = res + S[tot--];
    	unsigned long long ans = 0, ret = 0;
    	for (int i = 63; ~i; --i) {
    		if (res.__0 >> i & 1) ret |= 1ull << i;
    		else if (res.__1 >> i & 1) {
    			if ((ans | 1ull << i) <= z) {
    				ans |= 1ull << i;
    				ret |= 1ull << i;
    			}
    		}
    	}
    	return ret;
    }
    
    int main() {
    	n = read(), m = read(), __p = read();
    	for (int i = 1; i <= n; ++i) {
    		__Opt[i] = read(), __Num[i] = readllu();
    	}
    	for (int i = 1, a, b; i < n; ++i) {
    		a = read(), b = read();
    		addedge(a, b);
    	}
    	dfs1(1), dfs2(top[1] = 1);
    	for (int i = 1; i <= n; ++i) Opt[dfn[i]] = __Opt[i], Num[dfn[i]] = __Num[i];
    	SgT::build(1, 1, n);
    
    	while (m --> 0) {
    		static int op, x, y;
    		static unsigned long long z;
    		op = read(), x = read(), y = read(), z = readllu();
    		if (op == 1) {
    			printf("%llu
    ", query(x, y, z));
    		} else {
    			SgT::modify(dfn[x], y, z);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    204. Count Primes (Integer)
    203. Remove Linked List Elements (List)
    202. Happy Number (INT)
    201. Bitwise AND of Numbers Range (Bit)
    200. Number of Islands (Graph)
    199. Binary Tree Right Side View (Tree, Stack)
    198. House Robber(Array; DP)
    191. Number of 1 Bits (Int; Bit)
    190. Reverse Bits (Int; Bit)
    189. Rotate Array(Array)
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10286499.html
Copyright © 2020-2023  润新知