标签:线段树
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