标签:线段树
2 10 5 1 3 5 2 4 5 1 1 8 2 3 6 1 8 8 10 6 1 2 5 2 3 4 1 0 8 2 2 5 1 4 4 1 2 3
[pre]3 7 2 1 9 4 Can not put any one. 2 6 2 0 9 4 4 5 2 3 [/pre]
/************************************************************************* > File Name: seg_8.cpp > Author: ALex > Mail: 405045132@qq.com > Created Time: 2015年01月11日 星期日 16时27分59秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 50010; struct node { int l, r; int add; int cnt; //空花瓶数目 }tree[N << 2]; void pushdown (int p) { if (tree[p].add != -1) { if (tree[p].add == 1) { tree[p << 1].cnt = 0; tree[p << 1 | 1].cnt = 0; tree[p << 1].add = tree[p].add; tree[p << 1 | 1].add = tree[p].add; } else { tree[p << 1].cnt = tree[p << 1].r - tree[p << 1].l + 1; tree[p << 1 | 1].cnt = tree[p << 1 | 1].r - tree[p << 1 | 1].l + 1; tree[p << 1].add = tree[p].add; tree[p << 1 | 1].add = tree[p].add; } tree[p].add = -1; } } void build (int p, int l, int r) { tree[p].l = l; tree[p].r = r; tree[p].cnt = r - l + 1; tree[p].add = -1; if (l == r) { return; } int mid = (l + r) >> 1; build (p << 1, l, mid); build (p << 1 | 1, mid + 1, r); } void update (int p, int l, int r, int sa) { if (l == tree[p].l && tree[p].r == r) { if (sa) { tree[p].cnt = 0; //放花 tree[p].add = 1; } else { tree[p].cnt = tree[p].r - tree[p].l + 1; //取花 tree[p].add = 0; } return; } pushdown (p); int mid = (tree[p].l + tree[p].r) >> 1; if (r <= mid) { update (p << 1, l, r, sa); } else if (l > mid) { update (p << 1 | 1, l, r, sa); } else { update (p << 1, l, mid, sa); update (p << 1 | 1, mid + 1, r, sa); } tree[p].cnt = tree[p << 1].cnt + tree[p << 1 | 1].cnt; // printf("区间[%d, %d] 有 %d 个 空花瓶\n", tree[p].l, tree[p].r, tree[p].cnt); } int query_num (int p, int l, int r) { if (l == tree[p].l && r == tree[p].r) { return tree[p].cnt; } pushdown (p); int mid = (tree[p].l + tree[p].r) >> 1; if (r <= mid) { return query_num (p << 1, l, r); } else if (l > mid) { return query_num (p << 1 | 1, l, r); } else { return query_num (p << 1, l, mid) + query_num (p << 1 | 1, mid + 1, r); } } int dfs (int p, int l, int r, int x) { if (tree[p].l == tree[p].r) { return tree[p].l; } pushdown (p); int mid = (tree[p].l + tree[p].r) >> 1; if (r <= mid) { return dfs (p << 1, l, r, x); } else if (l > mid) { return dfs (p << 1 | 1, l, r, x); } else { int cnt = query_num (1, l, mid); if (cnt >= x) { return dfs (p << 1, l, mid, x); } else { return dfs (p << 1 | 1, mid + 1, r, x - cnt); } } } int main() { int t; scanf("%d", &t); while (t--) { int n, m, k, x, f; scanf("%d%d", &n, &m); build (1, 0, n - 1); while (m--) { scanf("%d%d%d", &k, &x, &f); if (k == 2) { int cnt = query_num (1, x, f); printf("%d\n", f - x + 1 - cnt); update (1, x, f, 0); } else { int cnt = query_num (1, x, n - 1); if (cnt == 0) { printf ("Can not put any one.\n"); continue; } int s = dfs (1, x, n - 1, 1); if (cnt >= f) { int e = dfs(1, x, n - 1, f); printf("%d %d\n", s, e); update (1, s, e, 1); } else { int e = dfs(1, x, n - 1, cnt); printf("%d %d\n", s, e); update (1, s, e, 1); } } } printf("\n"); } return 0; }
标签:线段树
原文地址:http://blog.csdn.net/guard_mine/article/details/42613315