萌新刚学 OI 0.0000001 普朗克时间,线段树神奇代码悬两关求调
查看原帖
萌新刚学 OI 0.0000001 普朗克时间,线段树神奇代码悬两关求调
649315
心灵震荡楼主2023/7/17 16:34

rt

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 500005;
int n, m, u, v, k, opt;

struct node
{
	int l, r, tag, sum, maxi, lmax, rmax;
}tree[N << 2];

inline node push_up(int x)
{
	node a = tree[x << 1], b = tree[x << 1 | 1], f = tree[x];
	f.l = a.l, f.r = b.r, f.sum = a.sum + b.sum;
	
	if(a.maxi == a.sum) f.lmax = a.sum + b.lmax;
	else f.lmax = a.lmax;
	
	if(b.maxi == b.sum) f.rmax = b.sum + a.rmax;
	else f.rmax = a.rmax;
	
	f.maxi = max(a.maxi, max(a.rmax + b.lmax, b.maxi));
	return f;
}

inline void push_down(int x)
{
	if(!tree[x].tag) return;
	tree[x << 1].tag = tree[x << 1 | 1].tag = tree[x].tag;
	if(tree[x].tag == 1)
	{
		tree[x << 1].lmax = tree[x << 1].rmax = tree[x << 1].maxi = tree[x << 1].sum;
		tree[x << 1 | 1].lmax = tree[x << 1 | 1].rmax = tree[x << 1 | 1].maxi = tree[x << 1 | 1].sum;
	}
	else tree[x << 1].lmax = tree[x << 1].rmax = tree[x << 1].maxi =
		 tree[x << 1 | 1].lmax = tree[x << 1 | 1].rmax = tree[x << 1 | 1].maxi = 0;
	tree[x].tag = 0;
}

inline void update(int l, int r, int x, int f)
{
	push_down(x);
	if(l <= tree[x].l && tree[x].r <= r)
	{
		if(f == 1) return (void) (tree[x].tag = 1, tree[x].maxi = tree[x].lmax = tree[x].rmax = tree[x].sum);
		else return (void) (tree[x].tag = -1, tree[x].maxi = tree[x].lmax = tree[x].rmax = 0);
	}
	int mid = tree[x].l + tree[x].r >> 1;
	
	if(l <= mid) update(l, r, x << 1, f);
	if(r > mid) update(l, r, x << 1 | 1, f);
	tree[x] = push_up(x);
}

inline int query(int l, int r, int x, int k)
{
	push_down(x);
	if(l == r) return l;
	int mid = l + r >> 1;
	if(tree[x << 1].maxi >= k) return query(l, mid, x << 1, k);
	else if(tree[x << 1].rmax + tree[x << 1 | 1].lmax >= k)
		return tree[x << 1].r - tree[x << 1].rmax + 1;
	else return query(mid + 1, r, x << 1 | 1, k);
}

inline void build(int l, int r, int x)
{
	tree[x] = {l, r, 1, r - l + 1, 0, 0, 0};
	if(l == r) return (void) (tree[x].maxi = tree[x].lmax = tree[x].rmax = tree[x].sum);
	int mid = l + r >> 1;
	build(l, mid, x << 1);
	build(mid + 1, r, x << 1 | 1);
	tree[x] = push_up(x);
}

signed main()
{
	//ios :: sync_with_stdio(false);
	cin >> n >> m;
	build(1, n, 1);
	//for(int i = 1; i <= 25; i++) cout << i << ' ' << tree[i].l << ' ' << tree[i].r << ' ' << tree[i].maxi << ' ' << tree[i].lmax << ' ' << tree[i].rmax << ' ' << tree[i].tag << '\n';
	while(m--)
	{
		cin >> opt;
		if(opt == 1)
		{
			cin >> k;
			if(tree[1].maxi < k) cout << "0\n";
			else
			{
				int ll = query(1, n, 1, k);
				cout << ll << '\n';
				if(ll) update(ll, ll + k - 1, 1, -1);
			}
		}
		else
		{
			cin >> u >> v;
			update(u, u + v - 1, 1, 1);
		}
		//for(int i = 1; i <= 25; i++) cout << i << ' ' << tree[i].l << ' ' << tree[i].r << ' ' << tree[i].maxi << ' ' << tree[i].lmax << ' ' << tree[i].rmax << ' ' << tree[i].tag << '\n';
	}
	return 0;
}
2023/7/17 16:34
加载中...