hdu4614 Vases and Flowers 线段树+二分
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614
题意:
给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每个花瓶最多插一朵花。
然后有2个操作。
操作1,a b c ,往在a位置后面(包括a)插b朵花,输出插入的首位置和末位置。
操作2,a b ,输出区间[a , b ]范围内的花的数量,然后全部清空。
很显然这是一道线段树。区间更新,区间求和,
操作2,很显然就是线段树的区间求和,求出[a , b]范围内的花朵的数量,区间更新,将整个区间全部变成0。
操作1,这里我们首先需要找出他的首位置和末位置,所以需要二分他的位置。
首先我们二分他的首位置, l = a , r = n ,在这个区间内二分,找出第一个0的位置,那就是该操作的首位置pos1。
然后再二分他的末位置,l = pos1 , r = n ,找到第b个0,就是该操作的末位置pos2,然后区间更新[pos1 ,pos2]全部置为1
我最初主要是对二分不熟悉,做了几道二分的题目后再做这道题就很快了。。。。
很裸的一道线段树了,一定要用lazy思想设置flag标记位,不能更新到低,否则会超时的。。。。
代码:
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 #define maxn 50010 9 int n,m; 10 class node 11 { 12 public: 13 int l; 14 int r; 15 int sum; 16 int flag; 17 }; 18 node segTree[maxn*3]; 19 void Build(int num, int l, int r) 20 { 21 segTree[num].l=l; 22 segTree[num].r=r; 23 segTree[num].sum=0; 24 segTree[num].flag=0; 25 if(l==r) return; 26 int mid=(l+r)/2; 27 Build(num*2,l,mid); 28 Build(num*2+1,mid+1,r); 29 } 30 int query(int num, int l, int r) 31 { 32 if(segTree[num].l ==l && segTree[num].r==r) 33 { 34 return segTree[num].sum; 35 } 36 int mid=(segTree[num].l + segTree[num].r)/2; 37 if(segTree[num].flag==1) 38 { 39 segTree[num*2].sum=(segTree[num*2].r - segTree[num*2].l +1); 40 segTree[num*2+1].sum=(segTree[num*2+1].r- segTree[num*2+1].l +1); 41 segTree[num*2].flag=1; 42 segTree[num*2+1].flag=1; 43 segTree[num].flag=0; 44 } 45 if(segTree[num].flag ==-1) 46 { 47 segTree[num*2].sum=segTree[num*2+1].sum=0; 48 segTree[num*2].flag=segTree[num*2+1].flag=-1; 49 segTree[num].flag=0; 50 } 51 if(r <=mid) return query(num*2,l,r); 52 else if(l >mid ) return query(num*2+1,l,r); 53 else 54 { 55 return query(num*2,l,mid)+query(num*2+1,mid+1,r); 56 } 57 } 58 void Update1(int num,int l, int r) 59 { 60 if(segTree[num].flag==1) return; 61 if(segTree[num].l ==l && segTree[num].r==r) 62 { 63 segTree[num].sum=r-l+1; 64 segTree[num].flag=1; 65 return ; 66 } 67 int mid=(segTree[num].l + segTree[num].r)/2; 68 if(segTree[num].flag==-1) 69 { 70 segTree[num*2].sum=segTree[num*2+1].sum=0; 71 segTree[num*2].flag=segTree[num*2+1].flag=-1; 72 segTree[num].flag=0; 73 } 74 if(r<=mid) Update1(num*2,l,r); 75 else if(l>mid) Update1(num*2+1,l,r); 76 else 77 { 78 Update1(num*2,l,mid); 79 Update1(num*2+1,mid+1,r); 80 } 81 segTree[num].sum=segTree[num*2].sum+segTree[num*2+1].sum; 82 } 83 void Update2(int num,int l,int r) 84 { 85 if(segTree[num].flag == -1) return ; 86 if(segTree[num].l == l && segTree[num].r ==r) 87 { 88 segTree[num].flag=-1; 89 segTree[num].sum=0; 90 return ; 91 } 92 int mid=(segTree[num].l +segTree[num].r)/2; 93 if(segTree[num].flag==1) 94 { 95 segTree[num*2].sum=(segTree[num*2].r -segTree[num*2].l +1); 96 segTree[num*2+1].sum=(segTree[num*2+1].r -segTree[num*2+1].l +1); 97 segTree[num*2].flag=1; 98 segTree[num*2+1].flag=1; 99 segTree[num].flag=0; 100 } 101 if(r<=mid) Update2( num*2,l,r); 102 else if(l>mid) Update2(num*2+1,l,r); 103 else 104 { 105 Update2(num*2,l,mid); 106 Update2(num*2+1,mid+1,r); 107 } 108 segTree[num].sum=segTree[num*2].sum+segTree[num*2+1].sum; 109 } 110 int main() 111 { 112 int t; 113 scanf("%d",&t); 114 while(t--) 115 { 116 int k; 117 int A,F,B; 118 scanf("%d%d",&n,&m); 119 Build(1,1,n); 120 while(m--) 121 { 122 scanf("%d",&k); 123 if(k==1) 124 { 125 scanf("%d%d",&A,&F); 126 A++; 127 int tol=n-A+1-query(1,A,n); 128 if(tol==0) 129 { 130 cout<<"Can not put any one."<<endl; 131 continue; 132 } 133 134 if(tol<F) F=tol; 135 int l=A; 136 int r=n; 137 int mid; 138 int pos1=n+1,pos2=n+1; 139 while(l<=r) 140 { 141 mid=(l+r)/2; 142 int tol=mid-A+1-query(1,A,mid); 143 if(tol>=1) pos1=min(pos1,mid),r=mid-1; 144 else l=mid+1; 145 } 146 147 l=pos1; 148 r=n; 149 while(l<=r) 150 { 151 mid=(l+r)/2; 152 int tol=mid-pos1+1-query(1,pos1,mid); 153 if(tol>=F) pos2=min(pos2,mid),r=mid-1; 154 else l=mid+1; 155 } 156 cout<<pos1-1<<" "<<pos2-1<<endl; 157 Update1(1,pos1,pos2); 158 } 159 else 160 { 161 scanf("%d%d",&A,&B); 162 A++;B++; 163 int tol=query(1,A,B); 164 cout<<tol<<endl; 165 Update2(1,A,B); 166 } 167 168 } 169 cout<<endl; 170 } 171 return 0; 172 }
。