1 poj 3667
题意:
支持两种操作 1 如果有连续长度大于D的房间,则输出最左的区间值, 否则输出0;2 将ql, qr区间的房间标记为 未入住
思路:节点维护三个域, 该节点的最大房间数,该节点左端点起的最大房间数, 该房间右端点起的最大连续房间数,用线段树进行更新和查询
#include
#include
using namespace std;
const int maxn = 50010;
typedef struct
{
int s, l, r;
}node;
node a[maxn*4];
int col[maxn*4], ql, qr;
int n, m, t, v;
void construct(int o, int l, int r)
{
a[o].s = a[o].l = a[o].r = r-l+1;
col[o] = -1;
if(l == r) return;
int m = (l+r) / 2;
construct(2*o, l, m);
construct(2*o+1, m+1, r);
}
void pushdown(int o, int l, int r)
{
int m = (l+r) / 2;
if(col[o] != -1)
{
a[2*o].s = a[2*o].l = a[2*o].r = col[o] ? 0 : m-l+1;
a[2*o+1].s = a[2*o+1].l = a[2*o+1].r = col[o] ? 0: r-m;
col[2*o] = col[2*o+1] = col[o];
col[o] = -1;
}
}
void pushup(int o, int l, int r)
{
int m = (l+r) / 2;
a[o].l = a[2*o].l + (a[2*o].l==m-l+1 ? a[2*o+1].l : 0);
a[o].r = a[2*o+1].r + (a[2*o+1].r==r-m ? a[2*o].r : 0);
a[o].s = max(a[2*o].r+a[2*o+1].l, max(a[2*o].s, a[2*o+1].s));
col[o] = -1;
}
int query(int o, int l, int r)
{
if(a[o].l >= v)
return l;
pushdown(o, l, r);
int m = (l+r)/2;
if(a[2*o].s >= v) return query(2*o, l, m);
if(a[2*o].r+a[2*o+1].l >= v) return m-a[2*o].r+1;
return query(2*o+1, m+1, r);
}
void update(int o, int l, int r)
{
if(ql<=l &&qr>=r)
{
col[o] = v;
a[o].s = a[o].l = a[o].r = col[o] ? 0 : r-l+1;
return;
}
pushdown(o, l, r);
int m = (l+r) / 2;
if(ql <= m) update(2*o, l, m);
if(qr > m) update(2*o+1, m+1, r);
pushup(o, l, r);
}
int main()
{
while(scanf("%d %d", &n, &m) == 2)
{
construct(1, 1, n);
while(m--)
{
scanf("%d", &t);
if(t == 1)
{
scanf("%d", &v);
if(a[1].s < v) puts("0");
else
{
ql = query(1, 1, n);
printf("%d\n", ql);
qr = ql+v-1;
v = 1;
update(1, 1, n);
}
}
else
{
scanf("%d %d", &ql, &v);
qr = ql+v-1;
v = 0;
update(1, 1, n);
}
}
}
return 0;
}
2 hdu 3397
和上一题差不多, 不多说
#include
#include
using namespace std;
const int maxn = 100010;
typedef struct
{
int s, l, r
}node;
node a[maxn*4];
int b[maxn], ql, qr;
int n, m, p, x, t;
char s[5];
void pushup(int o,int l, int r)
{
int m = (l+r) / 2;
a[o].l = a[2*o].l;
if(a[o].l==m-l+1 && b[m+1]>b[m])
a[o].l += a[2*o+1].l;
a[o].r = a[2*o+1].r;
if(a[o].r==r-m && b[m+1]>b[m])
a[o].r += a[2*o].r;
a[o].s = max(a[2*o].s, a[2*o+1].s);
if(b[m+1] > b[m])
a[o].s = max(a[o].s, a[2*o].r+a[2*o+1].l);
}
void construct(int o, int l, int r)
{
if(l == r)
{
a[o].s = a[o].l = a[o].r = 1;
return;
}
int m = (l+r) / 2;
construct(2*o, l, m);
construct(2*o+1, m+1, r);
pushup(o, l, r);
}
void update(int o, int l, int r)
{
if(l == r)
{
b[l] = x;
return;
}
int m = (l+r) / 2;
if(p <= m)
update(2*o, l, m);
else
update(2*o+1, m+1, r);
pushup(o, l, r);
}
int query(int o, int l, int r)
{
if(ql<=l && qr>=r)
return a[o].s;
int m = (l+r) / 2;
int ans = 0;
if(ql <= m)
ans = max(ans, query(2*o, l, m));
if(qr > m)
ans = max(ans, query(2*o+1, m+1, r));
if(ql<=m && qr>m && b[m+1]>b[m])
ans = max(ans, min(a[2*o].r, m-ql+1)+min(a[2*o+1].l, qr-m));
}
int main()
{
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &m);
for(int i=1; i<=n; i++)
scanf("%d", &b[i]);
construct(1, 1, n);
while(m--)
{
scanf("%s", s);
if(s[0] == 'U')
{
scanf("%d %d", &p, &x);
p++;
update(1, 1, n);
}
else
{
scanf("%d %d", &ql, &qr);
ql++, qr++;
printf("%d\n", query(1, 1, n));
}
}
}
return 0;
}