题意:n个花瓶,m个操作,花瓶里面有的有花,有的是空的。1操作是从a开始往右放b朵花,花瓶有了的不放,跳过,直到a右边都放满了花,多余的扔了。输出本次放花的起始位置
求和操作可以用线段树解决,操作1的放置的起始位置,通过二分求就可以
#include
#include
#include
#include
#include
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define maxn 100009
using namespace std;
int n, m, a[maxn * 8], is[8 * maxn];
void build (int x, int l, int r)
{
if (l == r)
{
a[x] = 1;
is[x] = -1;
return;
}
int mid = (l + r) >> 1;
build (2 * x, l, mid);
build (2 * x + 1, mid + 1, r);
a[x] = a[2 * x] + a[2 * x + 1];
is[x] = -1;
return;
}
int ask (int x, int l, int r, int la, int ra)
{
if (l > ra || r < la)
return 0;
if (la <= l && r <= ra)
{
if (is[x] == 0)
return 0;
if (is[x] == 1)
return r - l + 1;
return a[x];
}
int mid = (l + r) >> 1;
if (is[x] != -1)
{
is[2 * x] = is[2 * x + 1] = is[x];
a[2 * x] = is[x] * (mid - l + 1);
a[2 * x + 1] = is[x] * (r - mid);
a[x] = is[x] * (r - l + 1);
is[x] = -1;
}
return ask (2 * x, l, mid, la, ra) + ask (2 * x + 1, mid + 1, r, la, ra);
}
void set (int x, int l, int r, int la, int ra, int color)
{
//printf ("========== set (%d %d) %d %d ==%d\n", l, r, la, ra, color);
if (l > ra || r < la)
return;
if (la <= l && r <= ra)
{
is[x] = color;
a[x] = color * (r - l + 1);
return;
}
int mid = (l + r) >> 1;
if (is[x] != -1)
{
is[2 * x] = is[2 * x + 1] = is[x];
a[2 * x] = is[x] * (mid - l + 1);
a[2 * x + 1] = is[x] * (r - mid);
a[x] = is[x] * (r - l + 1);
is[x] = -1;
}
set (2 * x, l, mid, la, ra, color);
set (2 * x + 1, mid + 1, r, la, ra, color);
a[x] = a[2 * x] + a[2 * x + 1];
}
void print (int x, int l, int r)
{
// printf (" %d (%d, %d) == %d -> %d\n", x, l, r, a[x], is[x]);
if (l == r)
return;
int mid = (l + r) >> 1;
print (2 * x, l, mid);
print (2 * x + 1, mid + 1, r);
}
void debug ()
{
printf ("==================================================\n");
print (1, 1, n);
}
int main ()
{
int ti;
cin >> ti;
rep (f1, 1, ti)
{
cin >> n >> m;
build (1, 1, n);
while (m--)
{
//printf (" (ask 1-n) %d\n", ask (1, 1, n, 1, n));
//debug ();
int col, x, y;
scanf ("%d%d%d", &col, &x, &y);
if (col == 1)
{
x++;
int Max = ask (1, 1, n, x, n), L, R;
//printf ("Max -----------------------------------%d\n", Max);
if (Max == 0)
{
printf ("Can not put any one.\n");
continue;
}
int l = x, r = n;
while (l <= r)
{
int mid = (l + r) >> 1;
int p = ask (1, 1, n, x, mid);
if (p == 1)
L = mid;
if (p >= 1)
r = mid - 1;
else
l = mid + 1;
}
/*if (Max <= y)
{
printf ("%d %d\n", L - 1, n - 1);
set (1, 1, n, L, n, 0);
continue;
}*/
//last
l = L, r = n;
while (l <= r)
{
int mid = (l + r) >> 1;
int p = ask (1, 1, n, L, mid);
//printf ("er fen %d ---- %d\n", mid, p);
if (p == min (y, Max) )
R = mid;
if (p >= min (y, Max) )
r = mid - 1;
else
l = mid + 1;
}
printf ("%d %d\n", L - 1, R - 1);
set (1, 1, n, L, R, 0);
//printf ("ask ------ %d\n", ask (1, 1, n, L, R));
}
else
{
x++, y++;
printf ("%d\n", y - x + 1 - ask (1, 1, n, x, y));
set (1, 1, n, x, y, 1);
}
}
printf ("\n");
}
return 0;
}