当前位置: 代码迷 >> 综合 >> HDU - 4614 Vases and Flowers(线段树+二分)
  详细解决方案

HDU - 4614 Vases and Flowers(线段树+二分)

热度:83   发布时间:2023-12-17 02:48:06.0

题意:给你一排花盆,两种操作:第一种从i开始插花,插j朵,遇到有花的花盆就跳过。直到插完j朵花或者后面没有空花盆为止,输出从哪开始插,插到哪结束的区间。第二种是求i~j区间的花的总数,然后把这个区间的花全部拔掉。

终于自己手写了一个线段树,虽然花了一上午。其实这道题不难,当时求区间的时候j - i + 1,有一个不小心把+写成了-号,花了半上午,然后忽略了起始位置可能有花的情况,又花了半上午,算了,上代码:

其中二分是为了确定起始位置和结束位置,线段树是为了维护 区间。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>using namespace std;const int MAXN=50050;
int a[MAXN],ans[MAXN<<2],lazy[MAXN<<2];void PushUp(int rt)
{ans[rt]=ans[rt<<1]+ans[rt<<1|1];
}void Build(int l,int r,int rt)
{if (l==r){ans[rt]=a[l];return;}int mid=(l+r)>>1;Build(l,mid,rt<<1);Build(mid+1,r,rt<<1|1);PushUp(rt);
}void PushDown(int rt,int ln,int rn)//ln表示左子树元素结点个数,rn表示右子树结点个数
{if (lazy[rt]){if(lazy[rt] == -1) {lazy[rt<<1]=-1;lazy[rt<<1|1]=-1;ans[rt<<1]=0;ans[rt<<1|1]=0;lazy[rt]=0;}else {lazy[rt<<1]=1;lazy[rt<<1|1]=1;ans[rt<<1]=ln;ans[rt<<1|1]=rn;lazy[rt]=0;}}
}void Update(int L,int R,int C,int l,int r,int rt)
{if (L<=l&&r<=R){if(C == -1) {ans[rt]=0;lazy[rt]=-1;return;}else {ans[rt] = (r - l + 1);lazy[rt] = 1;return;}}int mid=(l+r)>>1;PushDown(rt,mid-l+1,r-mid);if (L<=mid) Update(L,R,C,l,mid,rt<<1);if (R>mid) Update(L,R,C,mid+1,r,rt<<1|1);PushUp(rt);
}int Query(int L,int R,int l,int r,int rt)
{if (L<=l&&r<=R)return ans[rt];int mid=(l+r)>>1;PushDown(rt,mid-l+1,r-mid);//若更新只有点更新,不需要这句int ANS=0;if (L<=mid) ANS+=Query(L,R,l,mid,rt<<1);if (R>mid) ANS+=Query(L,R,mid+1,r,rt<<1|1);return ANS;
}int main()
{int T, n, m, p, q, t;cin >> T;while(T--) {cin >> n >> m;memset(a, 0, sizeof(a));memset(ans, 0, sizeof(ans));memset(lazy, 0, sizeof(lazy));while(m--) {cin >> p >> q >> t;q++;t;if(p == 1) {int l = q;int r = n;int c;if(Query(q, q, 1, n, 1)) {c = l - Query(1, l, 1, n, 1);while(l < r) {int mid = (l + r) / 2;if(mid - Query(1, mid, 1, n, 1) != c) {r = mid;}else {l = mid + 1;}}q = r;}l = q;r = n;while(l < r) {int mid = (l + r) / 2;if(mid - q + 1 - Query(q, mid, 1, n, 1) >= t) {r = mid;}else {l = mid + 1;}}if(r == n) {if(Query(q, r, 1, n, 1) <= r - q + 1 - t) {cout << q - 1 << ' ' << r - 1 << endl;Update(q, r, 1, 1, n, 1);}else if(Query(q, r, 1, n, 1) == r - q + 1) {cout << "Can not put any one.\n";}else {c = r - q + 1 - Query(q, r, 1, n, 1);l = q;r = n;while(l < r) {int mid = (l + r) / 2;if(mid - q + 1 - Query(q, mid, 1, n, 1) == c) {r = mid;}else {l = mid + 1;}}cout << q - 1 << ' ' << r - 1 << endl;Update(q, r, 1, 1, n, 1);}}else {cout << q - 1 << ' ' << r - 1 << endl;Update(q, r, 1, 1, n, 1);}}else {cout << Query(q, t + 1, 1, n, 1) << endl;Update(q, t + 1, -1, 1, n, 1);}}cout << endl;}return 0;
}