ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AtCoder Beginner Contest 237 G - Range Sort Query

2022-02-04 09:02:11  阅读:241  来源: 互联网

标签:Sort AtCoder Beginner int t2 modify t1 cnt2 cnt1


原题链接 G - Range Sort Query

思路:

\(x\)是固定的,所以考虑将排序维护成0 1串,为\(p_i < x\)为\(0\),那么\(p_i \geq x\)为\(1\),那么这样就可以用线段树维护了,我们可以维护每个区间1的个数,设为\(cnt\),对于升序来说,设我们需要更新的这个区间\([l, r]\),那么现在查询后,更新新的区间就是\([r - cnt + 1, 1]\)为\(1\),更新\([l, r - cnt]\)为\(0\),所以维护两颗线段树,一颗是\(p_i \geq x\),另一颗是\(p_i \geq x + 1\),那么最后可以从\(1 - N\)遍历查询,若\(t1.query(1, i, i)\)与\(t2.query(1, i, i)\)两者不相等,说明这就是我们要找的那个位置。

一开始把懒标记初值设成了0,怎么也不对,后来对拍了半天才发现有是因为懒标记有0 1值,那初值肯定不能是0 1,所以改成-1,就对了。

#include <bits/stdc++.h>

using namespace std;


const int N = 2E5 + 10;
int w[N], n, q, x;

struct SegMentTree {
	struct node {
		int l, r;
		int val, tag;
	}tr[N * 4];

	void pushup(int u) {
		tr[u].val = tr[u << 1].val + tr[u << 1 | 1].val;
	}  

	void pushdown(int u) {
		auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
		if (~root.tag) {
			left.tag = root.tag;
			left.val = root.tag * (left.r - left.l + 1);

			right.tag = root.tag;
			right.val = root.tag * (right.r - right.l + 1);
			root.tag = -1;
		}
	}

	void build(int u, int l, int r, int x) {
		tr[u] = {l, r};
		tr[u].tag = -1;
		if (l == r) {
			tr[u].val = (w[l] >= x);
			//tr[u].tag = 0;
			return;
		}
		int mid = l + r >> 1;
		build(u << 1, l, mid, x), build(u << 1 | 1, mid + 1, r, x);
		pushup(u);
	}

	void modify(int u, int l, int r, int x) {
		if (l <= tr[u].l && tr[u].r <= r) {
			tr[u].tag = x;
			tr[u].val = x * (tr[u].r - tr[u].l + 1);
			return;
		}
		
		pushdown(u);
		int mid = tr[u].l + tr[u].r >> 1;
		if (l <= mid) modify(u << 1, l, r, x);
		if (r > mid) modify(u << 1 | 1, l, r, x);
		pushup(u);
	}

	int query(int u, int l, int r) {
		if (l <= tr[u].l && tr[u].r <= r) {
			return tr[u].val;
		}
		
		pushdown(u);
		int mid = tr[u].l + tr[u].r >> 1;
		int res = 0;
		if (l <= mid) res += query(u << 1, l, r);
		if (r > mid) res += query(u << 1 | 1, l, r);
		return res;
	}
}t1, t2;

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	//freopen("D:\\cpeditor\\competition\\Atcoder\\abc237\\data.txt", "r", stdin);
	//freopen("D:\\cpeditor\\competition\\Atcoder\\abc237\\myans.txt", "w", stdout);
    cin >> n >> q >> x;
    for (int i = 1; i <= n; i++) cin >> w[i];
    t1.build(1, 1, n, x);
	t2.build(1, 1, n, x + 1);
    while (q--) {
    	int op, l, r;
    	cin >> op >> l >> r;
    	int cnt1 = t1.query(1, l, r), cnt2 = t2.query(1, l, r);
    	int len = r - l + 1;
    	if (op == 1) { //asc
    		if (cnt1 && cnt1 != len) {
    			t1.modify(1, l, r - cnt1, 0); t1.modify(1, r - cnt1 + 1, r, 1); 
    		}
    		if (cnt2 && cnt2 != len) {
    			t2.modify(1, l, r - cnt2, 0); t2.modify(1, r - cnt2 + 1, r, 1); 
    		}
    	} else {
    		if (cnt1 && cnt1 != len) {
    			t1.modify(1, l, l + cnt1 - 1, 1); t1.modify(1, l + cnt1, r, 0);
    		}
    		if (cnt2 && cnt2 != len) {
    			t2.modify(1, l, l + cnt2 - 1, 1); t2.modify(1, l + cnt2, r, 0);
    		}
    	}
    }

   // cout << "test" << endl;
    for(int i = 1; i <= n; i++) {
    	//cout << t1.query(1, i, i) << " " << t2.query(1, i, i) << endl;
    	if(t1.query(1, i, i) != t2.query(1, i, i)) {
    		cout << i << "\n";
    	}
	}

	//fclose(stdin);
	//fclose(stdout);

	return 0;
}

标签:Sort,AtCoder,Beginner,int,t2,modify,t1,cnt2,cnt1
来源: https://www.cnblogs.com/ZhengLijie/p/15862453.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有