// hdu 4614
// 题意 机器翻译 爱丽丝非常受欢迎,每天都能收到很多花。她有N个花瓶,编号从0到N-1。当她收到几朵花时,她会尝试将它们放在花瓶中,一朵花放在一个花瓶中。她随机选择花瓶A,并尝试在花瓶中放一朵花。如果花瓶中没有花,她会在上面放一朵花,否则她会跳过这个花瓶。然后她将尝试放入花瓶A + 1,A + 2,...,N-1,直到没有花了,或者她尝试了花瓶N-1。剩下的花将被丢弃。当然,有时她会清洗花瓶。由于花瓶过多,她随机选择清洗编号从A到B(A <= B)的花瓶。清洗过的花瓶中的花将被丢弃。
第一行包含一个整数T,表示测试用例的数量。
对于每个测试用例,第一行包含两个整数N(1 <N <50001)和M(1 <M <50001)。N是花瓶的数量,M是爱丽丝的业务。接下来的M行中的每行包含三个整数。一行的第一个整数是K(1或2)。如果K为1,则跟随两个整数A和F。这意味着爱丽丝会收到F朵花,然后尝试先在花瓶A中放一朵花。如果K为2,则跟随两个整数A和B。这意味着所有者希望清洗编号从A到B(A <= B)的花瓶。
对于K为1的每个操作,输出花瓶的位置,爱丽丝将第一朵花和最后一朵花放在花瓶中,并用空格隔开。如果她不能放任何东西,则输出“不能放任何东西”。对于K为2的每个操作,输出丢弃的花朵数量。
1 /* 2 * @Promlem: hdu 4614 3 * @Time Limit: 2000ms 4 * @Memory Limit: 32768k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-12 14:11:16 7 * @LastEditTime: 2019-10-13 01:03:11 8 */ 9 #include<cstdio> 10 #include<algorithm> 11 #define L k<<1 12 #define R k<<1|1 13 #define mid (tree[k].l+tree[k].r)>>1 14 using namespace std; 15 const int MAXN = 50000+5; 16 17 struct segmemt_tree { 18 int l, r; 19 int num, f; 20 } tree[4*MAXN+1]; 21 22 inline void build(int k, int l, int r) { 23 tree[k].l = l; tree[k].r = r; 24 tree[k].num = 0; 25 tree[k].f = -1; 26 if(l == r) return ; 27 int m = mid; 28 build(L, l, m); 29 build(R, m+1, r); 30 } 31 32 inline void push_down(int k) { 33 tree[L].f = tree[R].f = tree[k].f; 34 int m = mid; 35 tree[L].num = (m-tree[k].l+1) * tree[k].f; 36 tree[R].num = (tree[k].r-m) * tree[k].f; 37 tree[k].f = -1; 38 } 39 40 inline int query(int k, int x, int y) {// 查询区间内插入花的数量 41 if(tree[k].l >= x && tree[k].r <= y) return tree[k].num; 42 if(tree[k].f != -1) push_down(k); 43 int m = mid; 44 int ans = 0; 45 if(x <= m) ans = query(L, x, y); 46 if(y > m) ans += query(R, x, y); 47 return ans; 48 } 49 50 inline int bin(int start, int end, int cnt) {// 二分查找 l=start 到 r=end 第cnt个空花瓶 51 int l = start, r = end; 52 while(l < r) { 53 int m = (l + r) / 2; 54 int t = (m - start + 1) - query(1, start, m); 55 if(t >= cnt) r = m; 56 else l = m + 1; 57 } 58 return l; 59 } 60 61 inline void change(int k, int x, int y, int v) { 62 if(tree[k].l >= x && tree[k].r <= y) { 63 tree[k].f = v; 64 tree[k].num = (tree[k].r - tree[k].l + 1) * v; 65 return ; 66 } 67 if(tree[k].f != -1) push_down(k); 68 int m = mid; 69 if(x <= m) change(L, x, y, v); 70 if(y > m) change(R, x, y, v); 71 tree[k].num = tree[L].num + tree[R].num; 72 } 73 74 int main() { 75 int T; 76 scanf("%d", &T); 77 while(T--) { 78 int n, m; 79 scanf("%d%d", &n, &m); 80 build(1, 0, n-1); 81 int op, x, y; 82 int s, e; 83 for(int i = 0; i != m; ++i) { 84 scanf("%d%d%d", &op, &x, &y); 85 if(op == 1) { 86 int one = query(1, x, n-1); 87 if(one == n-1-x+1) printf("Can not put any one. "); 88 else { 89 s = bin(x, n-1, 1);// 第一个空花瓶位置 90 e = bin(s, n-1, min(n-1-x+1-one, y));// 最后一个空花瓶位置 91 printf("%d %d ", s, e); 92 change(1, s, e, 1); 93 } 94 } 95 else printf("%d ", query(1, x, y)), change(1, x, y, 0); 96 } 97 printf(" "); 98 } 99 return 0; 100 }
附上一个很蠢的代码 TLE
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-12 14:11:16 7 * @LastEditTime: 2019-10-12 22:58:36 8 */ 9 #include<cstdio> 10 #define L k<<1 11 #define R k<<1|1 12 #define mid (tree[k].l+tree[k].r)>>1 13 using namespace std; 14 const int MAXN = 50000+4; 15 16 struct segmemt_tree { 17 int l, r, num; 18 int f; 19 } tree[4*MAXN+1]; 20 21 void build(int k, int l, int r) { 22 tree[k].l = l; tree[k].r = r; 23 tree[k].num = 0; 24 tree[k].f = 0; 25 if(l == r) return ; 26 int m = mid; 27 build(L, l, m); 28 build(R, m+1, r); 29 } 30 31 void down(int k) { 32 tree[L].num = tree[R].num = 0; 33 tree[L].f = tree[R].f = 1; 34 tree[k].f = 0; 35 } 36 37 int sx, ex, sum; 38 void update(int k, int x, int y, int op) { 39 if(op == 1 && !sum) return ; 40 // if(tree[k].num == tree[k].r-tree[k].l+1) return ; 41 if(tree[k].l >= x && tree[k].r <= y) { 42 if(tree[k].f) down(k); 43 if(op == 0) { 44 tree[k].f = 1; 45 sum += tree[k].num; 46 tree[k].num = 0; 47 } 48 else if(tree[k].l == tree[k].r) { 49 if(tree[k].num == 0) { 50 tree[k].num = 1; 51 if(sx == -1) sx = ex = tree[k].l; 52 else ex = tree[k].l; 53 --sum; 54 } 55 } 56 else { 57 int m = mid; 58 if(x <= x) update(L, x, y, op); 59 if(y > m) update(R, x, y, op); 60 tree[k].num = tree[L].num + tree[R].num; 61 } 62 return ; 63 } 64 if(tree[k].f) down(k); 65 int m = mid; 66 if(x <= m) update(L, x, y, op); 67 if(y > m) update(R, x, y, op); 68 tree[k].num = tree[L].num + tree[R].num; 69 } 70 71 int main() { 72 int T; 73 scanf("%d", &T); 74 while(T--) { 75 int n, m; 76 scanf("%d%d", &n, &m); 77 build(1, 0, n-1); 78 int op, x, y; 79 for(int i = 0; i != m; ++i) { 80 scanf("%d%d%d", &op, &x, &y); 81 if(op == 1) { 82 sx = ex = -1; 83 sum = y; 84 update(1, x, n-1, 1); 85 if(ex == -1) printf("Can not put any one. "); 86 else printf("%d %d ", sx, ex); 87 } 88 else sum = 0, update(1, x, y, 0), printf("%d ", sum); 89 } 90 printf(" "); 91 } 92 return 0; 93 }