一共n个盒子, 两种操作, 第一种是给出两个数x, y, 从第x个盒子开始放y朵花, 一个盒子只能放一朵, 如果某个盒子已经有了, 那么就跳过这个盒子放下面的盒子。 直到花放完了或者到了最后一个盒子。 输出放的第一朵花和最后一朵花的坐标, 如果一朵也没法放, 输出Can not put any one.
第二种操作, 给出l, r, 求l, r区间内有多少朵花, 输出, 并且将l, r内的盒子全部变空。
思路: 第二种操作比较简单, 区间查询然后区间置0就可以。
第一种操作, 首先查询[x, n]内一共有多少个盒子是空的, 如果全是满的, 直接输出Can not put any one. 设num为空盒子的数量, 那么显然y = min(y, num)。
接下来的问题就是找左右端点, 我是用的二分寻找左右端点, 具体的细节可以看代码。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 5e4+5; int sum[maxn<<2], cnt[maxn<<2], n; void pushUp(int rt) { sum[rt] = sum[rt<<1]+sum[rt<<1|1]; } void pushDown(int rt, int m) { if(~cnt[rt]) { cnt[rt<<1] = cnt[rt<<1|1] = cnt[rt]; sum[rt<<1] = cnt[rt]*(m-(m>>1)); sum[rt<<1|1] = cnt[rt]*(m>>1); cnt[rt] = -1; } } void update(int L, int R, int l, int r, int rt, int val) { if(L<=l&&R>=r) { cnt[rt] = val; sum[rt] = val*(r-l+1); return ; } pushDown(rt, r-l+1); int m = l+r>>1; if(L<=m) update(L, R, lson, val); if(R>m) update(L, R, rson, val); pushUp(rt); } int query(int L, int R, int l, int r, int rt) { if(L<=l&&R>=r) { return sum[rt]; } pushDown(rt, r-l+1); int m = l+r>>1, ret = 0; if(L<=m) ret += query(L, R, lson); if(R>m) ret += query(L, R, rson); return ret; } int bin(int l, int r, int val) { int ans, pos = l; while(l<=r) { int m = l+r>>1; if(m-pos+1-query(pos, m, 1, n, 1)>=val) { r = m-1; ans = m; } else { l = m+1; } } return ans; } int main() { int t, m, x, y, sign; cin>>t; while(t--) { scanf("%d%d", &n, &m); mem1(cnt); mem(sum); while(m--) { scanf("%d%d%d", &sign, &x, &y); x++; if(sign == 1) { int num = query(x, n, 1, n, 1); if(num == n-x+1) { puts("Can not put any one."); continue; } y = min(y, n-x+1-num); int l = bin(x, n, 1); int r = bin(l, n, y); printf("%d %d ", l-1, r-1); update(l, r, 1, n, 1, 1); } else { y++; printf("%d ", query(x, y, 1, n, 1)); update(x, y, 1, n, 1, 0); } } cout<<endl; } return 0; }