• 【HEOI2016】排序


    题面

    题解

    这题好神仙啊。。。

    我们二分这个位置上的数,

    然后当(val[i] geq mid)的位置设为(1),否则为(0)

    这样一来,这道题就变成了一个(01)序列排序,所以就可以用线段树实现(log_2n)排序(区间和以及区间覆盖)

    由于这个数列是(1-n)的全排列,所以二分出的结果就是答案。

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define RG register
    #define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
    
    inline int read()
    {
    	int data = 0, w = 1;
    	char ch = getchar();
    	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int maxn(1e5 + 10);
    int n, m, q, tree[maxn << 2], lazy[maxn << 2], a[maxn], opt[maxn], L[maxn], R[maxn];
    
    #define son(i) ((root << 1) | (i))
    inline void build(int x, int root = 1, int l = 1, int r = n)
    {
    	lazy[root] = 0;
    	if(l == r) { tree[root] = (a[l] >= x); return; }
    	int mid = (l + r) >> 1;
    	build(x, son(0), l, mid);
    	build(x, son(1), mid + 1, r);
    	tree[root] = tree[son(0)] + tree[son(1)];
    }
    
    inline void pushdown(int root, int l, int r, int mid)
    {
    	if(l == r) lazy[root] = 0;
    	if(!lazy[root]) return;
    	lazy[son(0)] = lazy[son(1)] = lazy[root];
    	if(lazy[root] == 1) tree[son(0)] = mid - l + 1, tree[son(1)] = r - mid;
    	else tree[son(0)] = tree[son(1)] = 0;
    	lazy[root] = 0;
    }
    
    inline void update(int ql, int qr, int val, int root = 1, int l = 1, int r = n)
    {
    	if(qr < l || r < ql) return;
    	if(ql <= l && r <= qr) { tree[root] = val * (r - l + 1); lazy[root] = val ? 1 : -1; return; }
    	int mid = (l + r) >> 1; pushdown(root, l, r, mid);
    	update(ql, qr, val, son(0), l, mid);
    	update(ql, qr, val, son(1), mid + 1, r);
    	tree[root] = tree[son(0)] + tree[son(1)];
    }
    
    inline int query(int ql, int qr, int root = 1, int l = 1, int r = n)
    {
    	if(qr < l || r < ql) return 0;
    	if(ql <= l && r <= qr) return tree[root];
    	int mid = (l + r) >> 1; pushdown(root, l, r, mid);
    	return query(ql, qr, son(0), l, mid) + query(ql, qr, son(1), mid + 1, r);
    }
    
    inline bool check(int mid)
    {
    	build(mid);
    	for(RG int i = 1; i <= m; i++)
    	{
    		int cnt = query(L[i], R[i]);
    		if(!opt[i])
    			update(R[i] - cnt + 1, R[i], 1),
    			update(L[i], R[i] - cnt, 0);
    		else
    			update(L[i], L[i] + cnt - 1, 1),
    			update(L[i] + cnt, R[i], 0);
    	}
    	return query(q, q);
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	file(cpp);
    #endif
    	n = read(); m = read();
    	for(RG int i = 1; i <= n; i++) a[i] = read();
    	for(RG int i = 1; i <= m; i++) opt[i] = read(), L[i] = read(), R[i] = read();
    	q = read(); int ans = 0;
    	for(RG int l = 1, r = n, mid; l <= r;)
    	{
    		mid = (l + r) >> 1;
    		if(check(mid)) ans = mid, l = mid + 1;
    		else r = mid - 1;
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    Decimal 格式化输出( 去掉多余的0和点)
    HTML Character Sets
    生成下面的模块时,启用了优化或没有调试信息
    PJBLog的CSS模板图
    .NET 实例化顺序
    Live Mail 报错 0x80048820 可能的处理方式
    Windows下将Ldif文件导入OpenLdap时的中文转换问题
    DataGrid中动态添加列
    Sip协议栈消息层的设计与实现
    Prism学习笔记模块之间通信的几种方式
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/9850723.html
Copyright © 2020-2023  润新知