hdu 4614 Vases and Flowers(线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614
题意:
给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每个花瓶最多插一朵花。
然后有2个操作。
1)a b 往在a位置后面(包括a)插b朵花,输出插入的首位置和末位置。
2)a b 输出区间[a , b ]范围内的花的数量,然后全部清空。
操作看起来挺简单的但写起来还是有点复杂的
首先建树的时候可以设置变量first与ends分别表示一个区间最先出现的0和最后出现的0,sum=0
表示没放东西,sum=1表示放了。我们可以用二分来查找插完b朵花后的结尾区间。然后在寻找这个
区间的first与ends值之后就简单了。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int M = 5e4 + 10;
struct TnT {
int l , r , num , add , first , ends;
}T[M << 2];
int n , m;
void build(int l , int r , int p) {
int mid = (l + r) >> 1;
T[p].l = l , T[p].r = r , T[p].add = T[p].num = 0 , T[p].first = l , T[p].ends = r;
if(l == r) {
return ;
}
build(l , mid , p << 1);
build(mid + 1 , r , (p << 1) | 1);
}
void pushup(int p) {
T[p].num = T[p << 1].num + T[(p << 1) | 1].num;
if(T[p << 1].first == -1) {
T[p].first = T[(p << 1) | 1].first;
}
else if(T[(p << 1) | 1].first == -1) {
T[p].first = T[p << 1].first;
}
else {
T[p].first = min(T[(p << 1) | 1].first , T[p << 1].first);
}
if(T[(p << 1) | 1].ends == -1) {
T[p].ends = T[(p << 1) | 1].ends;
}
else if(T[(p << 1) | 1].ends == -1) {
T[p].ends = T[p << 1].ends;
}
else {
T[p].ends = max(T[(p << 1) | 1].ends , T[p << 1].ends);
}
}
void pushdown(int p) {
if(T[p].add == 1) {
T[p << 1].num = T[p << 1].r - T[p << 1].l + 1;
T[p << 1].first = -1;
T[p << 1].ends = -1;
T[(p << 1) | 1].num = T[(p << 1) | 1].r - T[(p << 1) | 1].l + 1;
T[(p << 1) | 1].first = -1;
T[(p << 1) | 1].ends = -1;
T[p << 1].add = T[p].add;
T[(p << 1) | 1].add = T[p].add;
}
if(T[p].add == -1) {
T[p << 1].first = T[p << 1].l;
T[p << 1].ends = T[p << 1].r;
T[p << 1].num = 0;
T[(p << 1) | 1].num = 0;
T[p << 1].add = T[p].add;
T[(p << 1) | 1].first = T[(p << 1) | 1].l;
T[(p << 1) | 1].ends = T[(p << 1) | 1].r;
T[(p << 1) | 1].add = T[p].add;
}
T[p].add = 0;
}
int query(int l , int r , int p) {
int mid = (T[p].l + T[p].r) >> 1;
if(T[p].l == l && T[p].r == r) {
return T[p].num;
}
pushdown(p);
if(mid >= r) {
return query(l , r , p << 1);
}
else if(mid < l) {
return query(l , r , (p << 1) | 1);
}
else {
return query(l , mid , p << 1) + query(mid + 1 , r , (p << 1) | 1);
}
}
int queryfr(int l , int r , int p) {
int mid = (T[p].l + T[p].r) >> 1;
if(T[p].l == l && T[p].r == r) {
return T[p].first;
}
pushdown(p);
if(mid >= r) {
return queryfr(l , r , p << 1);
}
else if(mid < l) {
return queryfr(l , r , (p << 1) | 1);
}
else {
int ans = queryfr(l , mid , p << 1);
if(ans == -1) {
return queryfr(mid + 1 , r , (p << 1) | 1);
}
else {
return ans;
}
}
}
int queryed(int l , int r , int p) {
int mid = (T[p].l + T[p].l) >> 1;
if(T[p].l == l && T[p].r == r) {
return T[p].ends;
}
pushdown(p);
if(mid >= r) {
return queryed(l , r , p << 1);
}
else if(mid < l) {
return queryed(l , r , (p << 1) | 1);
}
else {
int ans = queryed(mid + 1 , r , (p << 1) | 1);
if(ans == -1) {
return queryed(l , mid , p << 1);
}
else {
return ans;
}
}
}
void updata(int l , int r , int p , int ad) {
int mid = (T[p].l + T[p].r) >> 1;
if(T[p].l == l && T[p].r == r) {
if(ad == 1) {
T[p].add = 1;
T[p].num = T[p].r - T[p].l + 1;
T[p].first = -1;
T[p].ends = -1;
return ;
}
if(ad == -1) {
T[p].add = -1;
T[p].num = 0;
T[p].first = T[p].l;
T[p].ends = T[p].r;
return ;
}
}
pushdown(p);
if(mid >= r) {
updata(l , r , p << 1 , ad);
}
else if(mid < l) {
updata(l , r , (p << 1) | 1 , ad);
}
else {
updata(l , mid , p << 1 , ad);
updata(mid + 1 , r , (p << 1) | 1 , ad);
}
pushup(p);
}
int bisearch(int sta , int sum) {
int l = sta , r = n;
int ans = n;
while(l <= r) {
int mid = (l + r) >> 1;
int gg = query(sta , mid , 1);
gg = mid - sta + 1 - gg;
if(gg >= sum) {
r = mid - 1;
ans = mid;
}
else {
l = mid + 1;
}
}
return ans;
}
int main() {
int t;
scanf("%d" , &t);
while(t--) {
scanf("%d%d" , &n , &m);
build(1 , n , 1);
for(int i = 1 ; i <= m ; i++) {
int k , a , f;
scanf("%d%d%d" , &k , &a , &f);
if(k == 1) {
a++;
int res = query(a , n , 1);
res = n - a + 1 - res;
if(res == 0) {
printf("Can not put any one.\n");
continue;
}
int sum = min(res , f);
int ed = bisearch(a , sum);
int fr = queryfr(a , ed , 1);
updata(fr , ed , 1 , 1);
printf("%d %d\n" , fr - 1 , ed - 1);
}
if(k == 2) {
a++ , f++;
int res = query(a , f , 1);
updata(a , f , 1 , -1);
printf("%d\n" , res);
}
}
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号