zoukankan      html  css  js  c++  java
  • 【Luogu P2824】[HEOI2016/TJOI2016]排序

    题目大意:

    给出一个 (1)(n) 的排列,(m) 次操作让某区间升序排或降序排,问 (q) 位置最后是多少。

    正文:

    本题十分巧妙,二分一个 (k),排列里大于 (k) 的数为 1,否则为 0,线段树维护这个 01串,进行排序,再根据 (q) 的位置调整二分范围。

    代码:

    
    struct SegmentTree
    {
    	struct Node
    	{
    		int l, r;
    	} SMT[N << 2];
    	int lazy[N << 2], val[N << 2];
    	
    	void pushup(int x)
    	{
    		val[x] = val[x << 1 | 1] + val[x << 1];
    	}
    	void pushdown(int x)
    	{
    		if(~lazy[x])
    		{
    			val[x << 1] = lazy[x] * (SMT[x << 1].r - SMT[x << 1].l + 1);
    			val[x << 1 | 1] = lazy[x] * (SMT[x << 1 | 1].r - SMT[x << 1 | 1].l + 1);
    			lazy[x << 1] = lazy[x];
    			lazy[x << 1 | 1] = lazy[x]; 
    			lazy[x] = -1;
    		}
    	}
    	
    	void prework()
    	{
    		memset(lazy, -1, sizeof lazy);
    		memset(val, 0, sizeof val);
    	}
    	
    	void build(int x, int l, int r, int k)
    	{
    		SMT[x].l = l, SMT[x].r = r;
    		if(l == r)
    		{
    			val[x] = a[l] >= k;
    			return ;
    		}
    		int mid = (l + r) >> 1;
    		build(x << 1, l, mid, k);
    		build(x << 1 | 1, mid + 1, r, k);
    		pushup(x);
    	}
    	void change(int p, int l, int r, int x, int y, int vall)
    	{
    		if (x <= l && r <= y)
    		{
    			val[p] = vall * (r - l + 1);
    			lazy[p] = vall;
    			return ;
    		}
    		if (l > y || r < x) return ;
    		pushdown(p);
    		int mid = (l + r) >> 1;
    		change(p << 1, l, mid, x, y, vall);
    		change(p << 1 | 1, mid + 1, r, x, y, vall);
    		pushup(p);
    	}
    	int query(int p , int l, int r, int x, int y)
    	{
    		if (x <= l && r <= y)
    		{
    			return val[p];
    		}
    		if (l > y || r < x) return 0;
    		pushdown(p);
    		int mid = (l + r) >> 1;
    		return query(p << 1, l, mid, x, y) + query(p << 1 | 1, mid + 1, r, x, y);
    	}
    }smt;
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++)
    		scanf ("%d", &a[i]);
    	for (int i = 1; i <= m ; i++)
    		scanf ("%d%d%d", &input[i][0], &input[i][1], &input[i][2]);
    	scanf ("%d", &q);
    	int l = 1, r = n, ans, mid;
    	while(l <= r)
    	{
    		mid = (l + r) >> 1;
    		smt.prework();
    		smt.build(1, 1, n, mid);
    		for (int i = 1; i <= m; i++)
    		{
    			int cntOne = smt.query(1, 1, n, input[i][1], input[i][2]);
    			if (input[i][0])
    			{
    				smt.change(1, 1, n, input[i][1], input[i][1] + cntOne - 1, 1);
    				smt.change(1, 1, n, input[i][1] + cntOne, input[i][2], 0);
    			}else
    			{
    				smt.change(1, 1, n, input[i][2] - cntOne + 1, input[i][2], 1);
    				smt.change(1, 1, n, input[i][1], input[i][2] - cntOne, 0);
    			}
    		}
    		int k = smt.query(1, 1, n, q, q);
    		if(k) ans = mid, l = mid + 1;else r = mid - 1;
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
    
  • 相关阅读:
    013.ES6 -对象字面量增强型写法
    012. ES6
    011. ES6 语法
    10. 9. Vue 计算属性的setter和getter 以及 计算属性的缓存讲解
    4. Spring MVC 数据响应方式
    3. SpringMVC 组件解析
    9. Vue 计算属性
    【洛谷 2984】给巧克力
    【洛谷 1821】捉迷藏 Hide and Seek
    【洛谷 1821】银牛派对Silver Cow Party
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/13363521.html
Copyright © 2011-2022 走看看