标签:二分查找 题意 查找 cto string eof modify tps ack
题目链接:https://vjudge.net/contest/332656#problem/H
题意:
n个花瓶,m个操作,花瓶里面有的有花,有的是空的。
1 x y 表示从第x个位置开始查y多花,若一朵花也插不上输出"Can not put any one.",反之输出插花的左位置和右位置。
2 操作是清除区间[a,b]的花。并输出清除了多少花。
思路:
线段树维护区间,然后每次二分查找满足要求的第一个位置。
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <random> 13 14 #define ll long long 15 const int maxn = 1e5 + 10; 16 17 int n,m; 18 19 struct Node { 20 int l,r; 21 int val; 22 int lazy; 23 }tree[maxn<<2]; 24 25 void build(int l,int r,int nod) { 26 tree[nod].l = l; 27 tree[nod].r = r; 28 if (l == r ) { 29 tree[nod].lazy = -1; 30 return ; 31 } 32 int mid = (l + r) >> 1; 33 build(l,mid,nod<<1); 34 build(mid+1,r,(nod<<1)+1); 35 } 36 37 void pushdown(int nod) { 38 tree[nod<<1].val = tree[nod].lazy*(tree[nod<<1].r-tree[nod<<1].l+1); 39 tree[(nod<<1)+1].val = tree[nod].lazy*(tree[(nod<<1)+1].r-tree[(nod<<1)+1].l+1); 40 tree[nod<<1].lazy = tree[(nod<<1)+1].lazy = tree[nod].lazy; 41 tree[nod].lazy = -1; 42 } 43 44 void modify(int x,int y,int z,int nod=1) { 45 int l = tree[nod].l,r = tree[nod].r; 46 if (x <= l && y >= r) { 47 tree[nod].lazy = z; 48 tree[nod].val = (r-l+1)*z; 49 return ; 50 } 51 if (tree[nod].lazy != -1 ) { 52 pushdown(nod); 53 } 54 int mid = (l + r) >> 1; 55 if (x <= mid) { 56 modify(x,y,z,nod<<1); 57 } 58 if (y > mid) { 59 modify(x,y,z,(nod<<1)+1); 60 } 61 tree[nod].val = tree[nod<<1].val + tree[(nod<<1)+1].val; 62 } 63 64 int query(int x,int y,int nod=1) { 65 int l = tree[nod].l,r = tree[nod].r; 66 if (x <= l && y >= r) { 67 return tree[nod].val; 68 } 69 if (tree[nod].lazy != -1 ) { 70 pushdown(nod); 71 } 72 int mid = (l + r ) >> 1; 73 int sum = 0; 74 if (x <= mid) { 75 sum += query(x,y,nod<<1); 76 } 77 if (y > mid) { 78 sum += query(x,y,(nod<<1)+1); 79 } 80 tree[nod].val = tree[nod<<1].val + tree[(nod<<1)+1].val; 81 return sum; 82 } 83 84 int find(int s,int num ) { // 查找满足从s开始插入num个的右边第一个位置 85 int temp = query(s,n,1); 86 if (temp == n-s+1) { 87 return -1; 88 } 89 if (n-s+1-temp < num) { 90 num = n-s+1-temp; 91 } 92 int l = s,r = n; 93 int mid,d; 94 int f = -1; 95 while (l <= r) { 96 mid = (l + r) >> 1; 97 d = mid-s+1-query(s,mid); 98 if (d > num) { 99 r = mid - 1; 100 } 101 else if (d < num) { 102 l = mid + 1; 103 } 104 else { 105 f = mid; 106 r = mid - 1; 107 } 108 } 109 return f; 110 } 111 112 int main() { 113 int T; 114 scanf("%d",&T); 115 while (T--) { 116 memset(tree,0, sizeof(tree)); 117 scanf("%d%d",&n,&m); 118 n--; 119 build(0,n,1); 120 while (m--) { 121 int d,x,y; 122 scanf("%d%d%d",&d,&x,&y); 123 if (d == 1) { 124 int temp = find(x,1); 125 if (temp == -1) { 126 printf("Can not put any one.\n"); 127 } 128 else { 129 int end = find(x,y); 130 printf("%d %d\n",temp,end); 131 modify(temp,end,1); 132 } 133 } 134 else { 135 printf("%d\n",query(x,y)); 136 modify(x,y,0); 137 } 138 } 139 printf("\n"); 140 } 141 return 0; 142 }
标签:二分查找 题意 查找 cto string eof modify tps ack
原文地址:https://www.cnblogs.com/-Ackerman/p/11729075.html