• CF543E Listening to Music


    题面

    空间只有$64 ext{MB}$!!!

    题解

    (据说正解是毒瘤分块套分块)

    按照权值从大到小排序,对所有能够覆盖到它的区间的左端点打个标记

    按照值域建一棵主席树就可以了

    区间查询最大值,用$m$减去它即可

    如何卡空间???

    1. 用位域将主席树的节点信息压到一个unsigned long long
    2. 将叶节点改成一个值,节省空间。(但是还是要开40倍)
    3. 永久化的标记和值压在一起。

    最后以大约$63 ext{MB}$的空间卡了过去。

    代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #define RG register
    #define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
    #define clear(x, y) memset(x, y, sizeof(x))
    
    inline int read()
    {
    	int data = 0, w = 1; char ch = getchar();
    	while(ch != '-' && (!isdigit(ch))) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int maxn(2e5 + 10), INT_MAX(1e9);
    #define lmax (l == mid ? int(t[rt].lson) : int(t[t[rt].lson].max))
    #define rmax (mid + 1 == r ? int(t[rt].rson) : int(t[t[rt].rson].max))
    
    struct node { unsigned long long max : 18, lson : 23, rson : 23; } t[maxn * 40];
    int cur, root[maxn], n, m, Q;
    std::pair<int, int> a[maxn];
    
    int Insert(int p, int l, int r, int ql, int qr)
    {
    	if(l == r) return p + 1;
    	int rt = ++cur; t[rt] = t[p];
    	if(ql <= l && r <= qr) return ++t[rt].max, rt;
    	int mid = (l + r) >> 1, tag = t[rt].max - std::max(lmax, rmax);
    	if(ql <= mid) t[rt].lson = Insert(t[p].lson, l, mid, ql, qr);
    	if(qr  > mid) t[rt].rson = Insert(t[p].rson, mid + 1, r, ql, qr);
    	t[rt].max = std::max(lmax, rmax) + tag; return rt;
    }
    
    int query(int rt, int l, int r, int ql, int qr)
    {
    	if(l == r) return rt;
    	if(ql <= l && r <= qr) return t[rt].max;
    	int mid = (l + r) >> 1, ans = 0, tag = t[rt].max - std::max(lmax, rmax);
    	if(ql <= mid) ans = std::max(ans, query(t[rt].lson, l, mid, ql, qr));
    	if(qr  > mid) ans = std::max(ans, query(t[rt].rson, mid + 1, r, ql, qr));
    	return ans + tag;
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	file(cpp);
    #endif
    	n = read(), m = read();
    	for(RG int i = 1; i <= n; i++) a[i] = std::make_pair(-read(), i);
    	std::sort(a + 1, a + n + 1);
    	for(RG int i = 1; i <= n; i++)
    	{
    		int ql = std::max(1, a[i].second - m + 1);
    		int qr = std::min(a[i].second, n - m + 1);
    		root[i] = Insert(root[i - 1], 1, n - m + 1, ql, qr);
    	}
    	Q = read(); int ans = 0;
    	while(Q--)
    	{
    		int l = read(), r = read(), x = read() ^ ans;
    		int id = std::upper_bound(a + 1, a + n + 1,
    				std::make_pair(-x, INT_MAX)) - a - 1;
    		printf("%d
    ", ans = m - query(root[id], 1, n - m + 1, l, r));
    	}
    	return 0;
    }
    
  • 相关阅读:
    OptiMSoC
    xilinx官方设计指导
    Essential of FPGA Design
    数据结构学习记录_2019.02.22
    C语言学习记录_2019.02.12
    C语言学习记录_2019.02.10
    数据结构学习记录_2019.02.10
    数据结构学习记录_2019.02.09
    C语言学习记录_2019.02.09
    C语言学习记录_2019.02.08
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10210611.html
Copyright © 2020-2023  润新知