久违的线段树,好久没敲了,比赛的时候也没心思看,之前卡题卡太久
成段更新,特别之处,有个范围的更新是会超出 n 的值
三个每个节点的三个数据:(需要更新的数据)
(1) 区间内的花数量、
(2) 区间内最左边的空格的编号、
成段更新,特别之处,有个范围的更新是会超出 n 的值
三个每个节点的三个数据:(需要更新的数据)
(1) 区间内的花数量、
(2) 区间内最左边的空格的编号、
(3) 区间内最右边的空瓶的编号
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
const int maxn = 105000;
const int inf = 1000000000;
int min( int a, int b ){ return a < b ? a : b; }
int max( int a, int b ){ return a > b ? a : b; }
int del[maxn<<2], sum[maxn<<2], fid[maxn<<2], lid[maxn<<2];
int mov, first, last, num;
void pushdown( int rt, int l, int r )
{
int len = r - l + 1;
if( del[rt] == 1 )
{
del[rt<<1] = del[rt<<1|1] = del[rt];
sum[rt<<1] = len - len / 2;
sum[rt<<1|1] = len / 2;
lid[rt<<1] = fid[rt<<1] = -1;
lid[rt<<1|1] = fid[rt<<1|1] = -1;
del[rt] = 0;
}
else if( del[rt] == -1 )
{
del[rt<<1] = del[rt<<1|1] = del[rt];
sum[rt<<1|1] = sum[rt<<1] = 0;
fid[rt<<1] = l;
lid[rt<<1] = (l + r) >> 1;
fid[rt<<1|1] = (l + r) / 2 + 1;
lid[rt<<1|1] = r;
del[rt] = 0;
}
}
void pushup( int rt )
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
fid[rt] = min( min( fid[rt<<1] == -1 ? inf : fid[rt<<1], lid[rt<<1] == -1 ? inf : lid[rt<<1] ),
min( fid[rt<<1|1] == -1 ? inf : fid[rt<<1|1], lid[rt<<1|1] == -1 ? inf : lid[rt<<1|1] ) );
lid[rt] = max( max( fid[rt<<1], lid[rt<<1] ), max( fid[rt<<1|1], lid[rt<<1|1] ) );
if( fid[rt] == inf )fid[rt] = lid[rt];
}
void build( int l, int r, int rt )
{
del[rt] = 0;
sum[rt] = 0;
fid[rt] = l;
lid[rt] = r;
if( l == r )
return ;
int m = (l + r) >> 1;
build( lson );
build( rson );
}
void update( int L, int R, int sign, int l, int r, int rt )
{
if( sign == 2 )
{
if( L <= l && r <= R )
{
del[rt] = -1;
mov += sum[rt];
sum[rt] = 0;
fid[rt] = l;
lid[rt] = r;
return ;
}
}
else if( sign == 1 )
{
if( L <= l && r - l + 1 - sum[rt] <= num )
{
del[rt] = 1;
num -= r - l + 1 - sum[rt];
sum[rt] = r - l + 1;
if( fid[rt] != -1 && (first == -1 || fid[rt] < first) )
first = fid[rt];
if( lid[rt] != -1 && (last == -1 || lid[rt] > last) )
last = lid[rt];
fid[rt] = -1;
lid[rt] = -1;
return ;
}
}
pushdown( rt, l, r );
int m = (l + r) >> 1;
if( sign == 2 )
{
if( L <= m )update( L, R, sign, lson );
if( m < R )update( L, R, sign, rson );
}
if( sign == 1 )
{
if( m - l + 1 - sum[rt<<1] && L <= m && num > 0 )
update( L, R, sign, lson );
if( r - m - sum[rt<<1|1] && num > 0 )
update( L, R, sign, rson );
}
pushup( rt );
}
int main()
{
int T, n, q, sign, a, b;
scanf( "%d", &T );
while( T-- )
{
scanf( "%d%d", &n, &q );
build( 0, n - 1, 1 );
while( q-- )
{
scanf( "%d%d%d", &sign, &a, &b );
if( sign == 1 && sum[1] == n )
{
puts("Can not put any one.");
continue;
}
if( sign == 2 && a > b )swap( a, b );
if( sign == 2 )
mov = 0;
else
first = last = -1;
num = b;
update( a, b, sign, 0, n - 1, 1 );
if( sign == 2 )
printf( "%d\n", mov );
else
if( num != b )
printf( "%d %d\n", first, last );
else
puts("Can not put any one.");
}
puts("");
}
return 0;
}