蒟蒻48分线段树求调
查看原帖
蒟蒻48分线段树求调
524160
Lin_Master楼主2023/8/23 20:07


#include <iostream>
#include <cstdio>

using namespace std;

const int MAXN = 50005;
int a[MAXN];
struct Node {
	int len;
	int lNum;
	int rNum;
	int num;
	int tag;
}tree[MAXN * 4];
int n,m;

inline int lc (int p) {
	return p << 1;
}

inline int rc (int p) {
	return p << 1 | 1;
}

void pushUp (int p) {
	if (tree[lc(p)].num == tree[lc(p)].len) {
		tree[p].lNum = tree[lc(p)].num + tree[rc(p)].lNum;
	} else {
		tree[p].lNum = tree[lc(p)].lNum;
	}
	if (tree[rc(p)].num == tree[rc(p)].len) {
		tree[p].rNum = tree[rc(p)].num + tree[lc(p)].rNum;
	} else {
		tree[p].rNum = tree[rc(p)].rNum;
	}
	tree[p].num = tree[lc(p)].rNum + tree[rc(p)].lNum;
	tree[p].num = max(tree[lc(p)].num, tree[p].num);
	tree[p].num = max(tree[rc(p)].num, tree[p].num);
}

void buildTree (int p, int l, int r) {
	tree[p].len = (r - l + 1);
	if (l == r) {
		tree[p].num = tree[p].lNum = tree[p].rNum = 1;
		return ;
	}
	int mid = (r + l ) >> 1;
	buildTree(lc(p), l, mid);
	buildTree(rc(p), mid + 1, r);
	pushUp(p);
}

void moveTag (int p, int l, int r, int tag) {
	if (tag == 1) {
		tree[p].num = tree[p].lNum = tree[p].rNum = 0;
		tree[p].tag = 1;
	} else {
		tree[p].num = tree[p].lNum = tree[p].rNum = r - l + 1;
		tree[p].tag = 2;
	}
}

void pushDown (int p, int l, int r) {
	if (tree[p].tag == 0) {
		return ;
	}
	int mid = (r + l) >> 1;
	moveTag(lc(p), l, mid, tree[p].tag);
	moveTag(rc(p), mid + 1, r, tree[p].tag);
	tree[p].tag = 0;
}

int query (int p, int l, int r, int k) {
	if (l == r) {
		return l;
	}
	int mid = (l + r) >> 1;
	pushDown(p, l, r);
	if (tree[lc(p)].num >= k) {
		return query(lc(p), l, mid, k);
	}
	if (tree[lc(p)].rNum + tree[rc(p)].lNum >= k) {
		return mid + 1 - tree[lc(p)].rNum; 
	}
	if (tree[rc(p)].num >= k) {
		return query(rc(p), mid + 1, r, k);
	}
}

void checkIn (int p, int l, int r, int ql, int qr) {
	if (ql <= l && r <= qr) {
		tree[p].num = tree[p].lNum = tree[p].rNum = 0;
		tree[p].tag = 1;
		return ;
	}
	pushDown(p, l, r);
	int mid = (r + l) >> 1;
	if (mid >= ql) {
		checkIn(lc(p), l, mid, ql, qr);
	}
	if (mid < qr) {
		checkIn(rc(p), mid + 1, r, ql, qr);
	}
	pushUp(p);
}

void checkOut (int p, int l, int r, int ql, int qr) {
	if (ql <= l && r <= qr) {
		tree[p].num = tree[p].lNum = tree[p].rNum = r - l + 1;
		tree[p].tag = 2;
		return ;
	}
	pushDown(p, l, r);
	int mid = (r + l) >> 1;
	if (mid >= ql) {
		checkOut(lc(p), l, mid, ql, qr);
	}
	if (mid < qr) {
		checkOut(rc(p), mid + 1, r, ql, qr);
	}
	pushUp(p);
}

int main () {
	scanf("%d%d", &n, &m);
	buildTree(1,1,n);	
	while (m--) {
		int op, x, y;
		scanf("%d",&op);
		if (op == 1) {
			scanf("%d", &x);
			int pos = query(1,1,n,x);
			printf("%d\n", pos);
			if (pos != 0) {
				checkIn(1,1,n,pos,pos+x-1);
			}
		} else {
			scanf("%d%d",&x,&y);
			checkOut(1,1,n,x,x+y-1);
		}
	}
	return 0;
} 
2023/8/23 20:07
加载中...