• [HEOI2016/TJOI2016]排序


    ( ext{Solution})

    非常巧妙的二分答案
    因为只有一个询问,且答案满足单调性,所以二分答案 (mid)
    原序列中大于等于 (mid) 的数的位置赋为 (1),否则赋为 (0)
    然后走一遍排序操作,用线段树赋值完成排序
    最后检查 (q) 位置上的情况,(0) 就不行,(1) 就可以
    (mid) 越小越容易,越大越困难,临界点即为答案

    ( ext{Code})

    #include <cstdio>
    #include <cstring>
    #define ls (p << 1)
    #define rs (ls | 1)
    #define re register
    using namespace std;
    
    const int N = 1e5 + 5;
    int n, m, q, a[N];
    struct node{int op, l, r;}b[N];
    
    inline void read(int &x)
    {
    	x = 0; char ch = getchar();
    	while (ch < '0' || ch > '9') ch = getchar();
    	while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    }
    
    int tag[N << 2], sum[N << 2];
    
    inline void pushup(int p){sum[p] = sum[ls] + sum[rs];}
    inline void pushdown(int p, int l, int r)
    {
    	if (tag[p] == -1) return;
    	int mid = (l + r) >> 1;
    	if (!tag[p]) sum[ls] = mid - l + 1, sum[rs] = r - mid;
    	else sum[ls] = sum[rs] = 0;
    	tag[ls] = tag[rs] = tag[p], tag[p] = -1;
    }
    
    void update(int p, int l, int r, int x, int y, int v)
    {
    	if (x > r || y < l) return;
    	if (x <= l && r <= y) 
    	{
    		tag[p] = v, sum[p] = (v ? 0 : r - l + 1);
    		return;
    	}
    	pushdown(p, l, r);
    	int mid = (l + r) >> 1;
    	if (x <= mid) update(ls, l, mid, x, y, v);
    	if (y > mid) update(rs, mid + 1, r, x, y, v);
    	pushup(p);
    }
    
    int query_0(int p, int l, int r, int x, int y)
    {
    	if (x > r || y < l) return 0;
    	if (x <= l && r <= y) return sum[p];
    	pushdown(p, l, r);
    	int mid = (l + r) >> 1, res = 0;
    	if (x <= mid) res = query_0(ls, l, mid, x, y);
    	if (y > mid) res += query_0(rs, mid + 1, r, x, y);
    	return res;
    }
    
    inline int check(int mid)
    {
    	memset(tag, 255, sizeof tag), memset(sum, 0, sizeof sum);
    	for(re int i = 1; i <= n; i++) update(1, 1, n, i, i, a[i] >= mid);
    	for(re int i = 1, l, r, num; i <= m; i++)
    	{
    		num = query_0(1, 1, n, b[i].l, b[i].r);
    		if (!b[i].op) l = b[i].l, r = b[i].l + num - 1,
    				update(1, 1, n, l, r, 0), update(1, 1, n, r + 1, b[i].r, 1);
    		else l = b[i].l, r = b[i].l + (b[i].r - b[i].l + 1 - num) - 1,
    			update(1, 1, n, l, r, 1), update(1, 1, n, r + 1, b[i].r, 0);
    	}
    	return !query_0(1, 1, n, q, q);
    }
    
    int main()
    {
    	read(n), read(m);
    	for(re int i = 1; i <= n; i++) read(a[i]);
    	int l = 1, r = n, mid, ans = 0;
    	for(re int i = 1; i <= m; i++) read(b[i].op), read(b[i].l), read(b[i].r);
    	read(q);
    	while (l <= r)
    	{
    		mid = (l + r) >> 1;
    		if (check(mid)) ans = mid, l = mid + 1;
    		else r = mid - 1;
    	}
    	printf("%d
    ", ans);
    }
    
  • 相关阅读:
    MySQL语句进行分组后的含有字段拼接方法
    架构基础
    自动化测试框架比较
    分布式系统中的概念--第一篇 一致性协议、一致性模型、拜占庭问题、租约
    如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗?
    分布式系统常用思想和技术总结(转)
    常用的Hash算法
    Sonar + Jacoco,强悍的UT, IT 双覆盖率统计(转)
    AWK处理日志入门(转)
    内存管理
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15041733.html
Copyright © 2020-2023  润新知