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 } 

原文地址:https://www.cnblogs.com/xiaozhuyang/p/hdu4614.html