zoukankan      html  css  js  c++  java
  • 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 } 

  • 相关阅读:
    CPU被挖矿,Redis竟是内鬼!
    图解四种 IO 模型
    用户态和内核态的区别是啥
    关于 RocketMQ ClientID 相同引发的消息堆积的问题
    玩转 ByteBuffer
    RocketMQ Consumer 启动时都干了些啥?
    网络协议之:基于UDP的高速数据传输协议UDT
    dart系列之:安全看我,dart中的安全特性null safety
    JetBrains又出神器啦!Fleet,体验飞一般的感觉
    网络协议之:还在用HTTP代理?弱爆了!快试试SOCKS5
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/hdu4614.html
Copyright © 2011-2022 走看看