• HDU-6356 Glad You Came 线段树+剪枝


    ( ext{原题链接})

    ( ext{题目大意})

    初始有一个长度为 (n) 的序列 (a),初始全 (0)

    (m) 次修改,每次修改 ((l,r,v)),让 (a_i = max(a_i, v), (lleq ileq r))。求出所有操作后的 (igoplus_{i = 1}^{n}{(i cdot a_i)})

    其中这 (m) 次修改的生成方式为:

    给定初始的(32)位非负整数 (X,Y,Z)

    调用 (3m) 次上图中的 (RNG61()),记结果为 (f_1,f_2,f_3...f_3m)。其中第 (i) 次修改的 (l_i,r_i,v_i) 为:

    [egin{cases} l_i &= minleft((f_{3 i - 2} mod n) + 1, (f_{3 i - 1} mod n) + 1 ight) \ r_i &= maxleft((f_{3 i - 2} mod n) + 1, (f_{3 i - 1} mod n) + 1 ight) \ v_i &= f_{3 i} mod 2^{30}end{cases} (i = 1, 2, cdots, m) ]

    (T) 组数据,每次给定 (n,m,X,Y,Z)

    (1 leq T leq 100),(1 leq n leq 10^5),(1 leq m leq 5 cdot 10^6),(0 leq X, Y, Z < 2^{30})

    (mathcal{Solution})

    其实就是区间取 (max),最后需要给出整个序列,朴素的线段树过不了,由于修改的 (l,r,v) 在一定程度上是随机的,所以考虑剪枝优化。

    第一种方法:标记永久化,维护一下每个区间的永久标记,最后在线段树上跑一边 dfs 统计结果(抄自oi-wiki)。剪枝优化:如果当前区间的永久标记已经 (geq) 当前修改的值,直接返回,不继续向下修改。

    第二种方法:维护区间最小值,这个就不用标记永久化了。剪枝优化:如果当前区间的最小值已经 (geq) 当前修改的值,直接返回,不继续向下修改。

    (mathcal{Code})

    第一种方法:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    namespace do_while_true {
    	#define ld double
    	#define ll long long
    	#define ui unsigned int
    	#define re register
    	#define pb push_back
    	#define fir first
    	#define sec second
    	#define pp std::pair
    	#define mp std::make_pair
    	const ll mod = 998244353;
    	template <typename T>
    	inline T Max(T x, T y) { return x > y ? x : y; }
    	template <typename T>
    	inline T Min(T x, T y) { return x < y ? x : y; }
    	template <typename T>
    	inline T Abs(T x) {	return x < 0 ? -x : x; }
    	template <typename T>
    	inline T& read(T& r) {
    		r = 0; bool w = 0; char ch = getchar();
    		while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    		while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    		return r = w ? -r : r;
    	}
    	template <typename T>
    	inline T qpow(T x, T y) {
    		re T sumq = 1; x %= mod;
    		while(y) {
    			if(y&1) sumq = sumq * x % mod;
    			x = x * x % mod;
    			y >>= 1;
    		}
    		return sumq;
    	}
    	char outch[110];
    	int outct;
    	template <typename T>
    	inline void print(T x) {
    		do {
    			outch[++outct] = x % 10 + '0';
    			x /= 10;
    		} while(x);
    		while(outct >= 1) putchar(outch[outct--]);
    	}
    }
    using namespace do_while_true;
    
    const int N = 100010;
    const int M = 5000100; 
    
    int n, m, a[N];
    ui f[M*3];
    #define ls tree[x].lson
    #define rs tree[x].rson
    int trnt = 1;
    struct SGT {
    	int l, r, lson, rson, tag;
    }tree[N<<1];
    
    void build(int x, int l, int r) {
    	tree[x].l = l; tree[x].r = r; tree[x].tag = 0;
    	if(l == r) return ;
    	ls = ++trnt; rs = ++trnt;
    	build(ls, l, (l+r)>>1); build(rs, tree[ls].r+1, r);
    }
    void modify(int x, int l, int r, int v) {
    	if(tree[x].tag >= v) return ;
    	if(tree[x].l >= l && tree[x].r <= r) {
    		tree[x].tag = Max(tree[x].tag, v);
    		return ;
    	}
    	int mid = (tree[x].l + tree[x].r) >> 1;
    	if(mid >= l) modify(ls, l, r, v);
    	if(mid < r) modify(rs, l, r, v);
    }
    void query(int x, int mx) {
    	mx = Max(tree[x].tag, mx);
    	if(tree[x].l == tree[x].r) {
    		a[tree[x].l] = mx;
    		return ;
    	}
    	query(ls, mx); query(rs, mx);
    }
    
    #undef ls
    #undef rs 
    
    void solve() {
    	read(n); read(m);
    	trnt = 1; build(1, 1, n);
    	ui x, y, z; read(x); read(y); read(z);
    	for(int i = 1; i <= 3 * m; ++i) { x = x ^ (x << 11),x = x ^ (x >> 4),x = x ^ (x << 5),x = x ^ (x >> 14);ui w = x ^ (y ^ z);x = y,y = z,z = w,f[i] = z;}
    	for(int i = 1, l, r, v; i <= m; ++i) {
    		l = Min(f[3*i-2] % n + 1, f[3*i-1] % n + 1);
    		r = Max(f[3*i-2] % n + 1, f[3*i-1] % n + 1);
    		v = f[3*i] % (1 << 30);
    		modify(1, l, r, v); 
    	}
    	query(1, 0); ll ans = 0;
    	for(int i = 1; i <= n; ++i)
    		ans ^= 1ll * i * a[i];
    	printf("%lld
    ", ans);
    }
    
    signed main() {
    	#ifndef ONLINE_JUDGE
    	freopen("in.txt", "r", stdin);
    	#endif
    	int T = 1;
    	read(T);
    	while(T--) solve();
    	fclose(stdin);
    	return 0;
    }
    

    第二种方法:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    namespace do_while_true {
    	#define ld double
    	#define ll long long
    	#define ui unsigned int
    	#define re register
    	#define pb push_back
    	#define fir first
    	#define sec second
    	#define pp std::pair
    	#define mp std::make_pair
    	const ll mod = 998244353;
    	template <typename T>
    	inline T Max(T x, T y) { return x > y ? x : y; }
    	template <typename T>
    	inline T Min(T x, T y) { return x < y ? x : y; }
    	template <typename T>
    	inline T Abs(T x) {	return x < 0 ? -x : x; }
    	template <typename T>
    	inline T& read(T& r) {
    		r = 0; bool w = 0; char ch = getchar();
    		while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    		while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    		return r = w ? -r : r;
    	}
    	template <typename T>
    	inline T qpow(T x, T y) {
    		re T sumq = 1; x %= mod;
    		while(y) {
    			if(y&1) sumq = sumq * x % mod;
    			x = x * x % mod;
    			y >>= 1;
    		}
    		return sumq;
    	}
    	char outch[110];
    	int outct;
    	template <typename T>
    	inline void print(T x) {
    		do {
    			outch[++outct] = x % 10 + '0';
    			x /= 10;
    		} while(x);
    		while(outct >= 1) putchar(outch[outct--]);
    	}
    }
    using namespace do_while_true;
    
    const int N = 100010;
    const int M = 5000100; 
    
    int n, m, a[N];
    ui f[M*3];
    #define ls tree[x].lson
    #define rs tree[x].rson
    int trnt = 1;
    struct SGT {
    	int l, r, lson, rson, mn, tag;
    }tree[N<<1];
    
    inline void pushup(int x) { tree[x].mn = Min(tree[ls].mn, tree[rs].mn); } 
    inline void pushdown(int x) {
    	if(tree[x].tag) {
    		int p = tree[x].tag; tree[x].tag = 0;
    		tree[ls].tag = Max(tree[ls].tag, p); tree[rs].tag = Max(tree[rs].tag, p);
    		tree[ls].mn = Max(tree[ls].mn, p);
    		tree[rs].mn = Max(tree[rs].mn, p);
    	}
    }
    
    void build(int x, int l, int r) {
    	tree[x].l = l; tree[x].r = r; tree[x].tag = 0; tree[x].mn = 0;
    	if(l == r) return ;
    	ls = ++trnt; rs = ++trnt;
    	build(ls, l, (l+r)>>1); build(rs, tree[ls].r+1, r);
    }
    void modify(int x, int l, int r, int v) {
    	if(tree[x].mn >= v) return ;
    	if(tree[x].l >= l && tree[x].r <= r) {
    		tree[x].mn = Max(tree[x].mn, v); 
    		tree[x].tag = Max(tree[x].tag, v);
    		return ;
    	}
    	pushdown(x);
    	int mid = (tree[x].l + tree[x].r) >> 1;
    	if(mid >= l) modify(ls, l, r, v);
    	if(mid < r) modify(rs, l, r, v);
    	pushup(x);
    }
    void query(int x) {
    	if(tree[x].l == tree[x].r) {
    		a[tree[x].l] = tree[x].mn;
    		return ;
    	}
    	pushdown(x);
    	query(ls); query(rs);
    }
    
    #undef ls
    #undef rs 
    
    void solve() {
    	read(n); read(m);
    	trnt = 1; build(1, 1, n);
    	ui x, y, z; read(x); read(y); read(z);
    	for(int i = 1; i <= 3 * m; ++i) { x = x ^ (x << 11),x = x ^ (x >> 4),x = x ^ (x << 5),x = x ^ (x >> 14);ui w = x ^ (y ^ z);x = y,y = z,z = w,f[i] = z;}
    	for(int i = 1, l, r, v; i <= m; ++i) {
    		l = Min(f[3*i-2] % n + 1, f[3*i-1] % n + 1);
    		r = Max(f[3*i-2] % n + 1, f[3*i-1] % n + 1);
    		v = f[3*i] % (1 << 30);
    		modify(1, l, r, v); 
    	}
    	query(1); ll ans = 0;
    	for(int i = 1; i <= n; ++i)
    		ans ^= 1ll * i * a[i];
    	printf("%lld
    ", ans);
    }
    
    signed main() {
    	#ifndef ONLINE_JUDGE
    	freopen("in.txt", "r", stdin);
    	#endif
    	int T = 1;
    	read(T);
    	while(T--) solve();
    	fclose(stdin);
    	return 0;
    }
    
  • 相关阅读:
    jQuery easyui datagrid pagenation 的分页数据格式
    Mysql操作符号
    jquery JSON的解析方式
    线程有几种状态
    工作日志2014-07-07
    leetcode
    Fragment中的setUserVisibleHint()方法调用
    Android开发:Eclipse中SqliteManager插件使用
    海南出差报告总结(案件录入与案件追踪系统)
    Python学习十四:filter()
  • 原文地址:https://www.cnblogs.com/do-while-true/p/14397600.html
Copyright © 2020-2023  润新知