zoukankan      html  css  js  c++  java
  • [洛谷P2114][NOI2014]起床困难综合症

    题目大意:有$n(nleqslant10^5)$个门,每个问有一个运算符$oplus(oplusin{OR,AND,XOR})$和一个参数$t(tleqslant10^9)$,求初始值在$[0,m(mleqslant10^9)]$中时,按顺序经过这$n$个门后最大的值是多少

    题解:发现$oplus$都是位运算,也就是说,它对于每一位都是独立的,可以把$(11dots11)_2$和$(00dots00)_2$,丢进去跑一遍,就可以跑出每一位原来是$1$或$0$会变成什么,然后从高位到低位贪心即可。

    卡点:



    C++ Code:(我先写了睡觉困难综合征,就把那道题挂成一条链,就通过了)

    #include <algorithm>
    #include <cstdio>
    #include <cctype>
    namespace __IO {
    	int x, ch;
    	inline int read() {
    		while (!isdigit(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 (!isdigit(ch = getchar())) ;
    		for (X = ch & 15; isdigit(ch = getchar()); ) X = X * 10 + (ch & 15);
    		return X;
    	}
    	inline char readc() {
    		while (!isalpha(ch = getchar())) ;
    		return ch;
    	}
    }
    using __IO::read;
    using __IO::readllu;
    using __IO::readc;
    
    const int maxn = 1000010;
    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;
    }
    
    unsigned long long __z;
    int main() {
    	n = read(), __z = readllu();
    	for (int i = 1; i <= n; ++i) {
    		__Opt[i] = readc(), __Num[i] = readllu();
    		switch (__Opt[i]) {
    			case 'A': __Opt[i] = 1; break;
    			case 'O': __Opt[i] = 2; break;
    			case 'X': __Opt[i] = 3;
    		}
    	}
    	for (int i = 1, a, b; i < n; ++i) {
    		a = i, b = i + 1;
    		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);
    
    	m = 1;
    	while (m --> 0) {
    		static int op, x, y;
    		static unsigned long long z;
    		op = 1, x = 1, y = n, z = __z;
    		if (op == 1) {
    			printf("%llu
    ", query(x, y, z));
    		} else {
    			SgT::modify(dfn[x], y, z);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    php连接mysql数据库基础
    控制操作
    巨慢IE9的加速
    推广邮件客户端(二):完美的IMAP客户端
    XPath 和 LINQ to XML 的比较
    推广邮件客户端(三):常用IMAP客户端介绍
    关于Git工具与GitHub
    Android开源项目(非组件)
    windows下使用Git获取Android源码
    Eclipse导入项目:No projects are found to import
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10286402.html
Copyright © 2011-2022 走看看