zoukankan      html  css  js  c++  java
  • kb-07线段树-12--二分查找区间边界

      1 /*
      2    hdu4614
      3    本题刚开始想能不能记录该区间最前面开始的点,最后面的点,区间空的数量;但是病不行
      4    然后线段树的本质是区间操作,所以!这题主要就是区间的空的全放满,只要定出区间的边界就好办了;
      5    这里用二分查找的方法,现计算满足数量的区间的尾,因为头已经确定了,及时不放花也是确定的,只要靠数量定出尾就可以了;
      6    然后就是区间修改了;
      7  */
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<algorithm>
     12 #define MAX_N 50001
     13 using namespace std;
     14 int n,m,first,last,num,x;
     15 struct tree
     16 {
     17     int l,r,fir,las,s,same,val;
     18 }tr[MAX_N*4];
     19 void build(int rt,int l,int r)
     20 {
     21     tr[rt].l=l;tr[rt].r=r;
     22     tr[rt].fir=l;
     23     tr[rt].las=r;
     24     tr[rt].s=0;
     25     tr[rt].val=r-l+1;
     26     if(l==r)
     27     {
     28         tr[rt].same=0;
     29         return ;
     30     }
     31     tr[rt].same=1;
     32     int mid=(l+r)/2;
     33     build(rt<<1,l,mid);
     34     build(rt<<1|1,mid+1,r);
     35 }
     36 void Pushup(int rt)
     37 {
     38     int l=rt<<1,r=rt<<1|1;
     39     if(tr[l].fir==0)
     40         tr[rt].fir=tr[r].fir;
     41     else tr[rt].fir=tr[l].fir;
     42     if(tr[r].las==0)
     43         tr[rt].las=tr[l].las;
     44     else tr[rt].las=tr[r].las;
     45     tr[rt].val=tr[r].val+tr[l].val;
     46 
     47 }
     48 void Pushdown(int rt)
     49 {
     50     if(tr[rt].l==tr[rt].r)
     51         return ;
     52     int l=rt<<1,r=rt<<1|1;
     53     if(tr[rt].same)
     54     {
     55         if(tr[rt].s==1)
     56         {
     57             tr[r].val=tr[l].val=0;
     58             tr[r].s=tr[l].s=1;
     59             tr[r].fir=tr[l].fir=0;
     60             tr[r].las=tr[l].las=0;
     61             tr[r].same=tr[l].same=1;
     62             tr[rt].same=0;
     63         }
     64         else
     65         {
     66             tr[r].val=tr[r].r-tr[r].l+1;
     67             tr[l].val=tr[l].r-tr[l].l+1;
     68             tr[r].s=tr[l].s=0;
     69             tr[r].same=tr[l].same=1;
     70             tr[r].fir=tr[r].l;
     71             tr[r].las=tr[r].r;
     72             tr[l].fir=tr[l].l;
     73             tr[l].las=tr[l].r;
     74             tr[rt].same=0;
     75         }
     76     }
     77 }
     78 void Update1(int rt,int l,int r)
     79 {
     80     if(x<=0)
     81         return ;
     82     if(tr[rt].val==0)
     83         return ;//在二分查找定区间后,少了这一句所以一直tle
     84     if(tr[rt].l==l&&tr[rt].val>0)
     85     {
     86         if(first==0)
     87             first=tr[rt].fir;
     88         if(tr[rt].val<=x)
     89         {
     90             if(last<tr[rt].las)
     91                 last=tr[rt].las;
     92             x-=tr[rt].val;
     93             tr[rt].same=1;
     94             tr[rt].s=1;
     95             tr[rt].val=0;
     96             tr[rt].fir=0;
     97             tr[rt].las=0;
     98             return ;
     99         }
    100     }
    101     if(tr[rt].l==tr[rt].r)
    102         return ;
    103     Pushdown(rt);
    104     int L=rt<<1,R=rt<<1|1;
    105     if(l<=tr[L].r)
    106     {
    107         if(r<=tr[L].r)
    108             Update1(L,l,r);
    109         else
    110             Update1(L,l,tr[L].r);
    111     }
    112     if(r>=tr[R].l)
    113     {
    114         if(l>=tr[R].l)
    115             Update1(R,l,r);
    116         else
    117             Update1(R,tr[R].l,r);
    118     }
    119     Pushup(rt);
    120 }
    121 void Update2(int rt,int l,int r)
    122 {
    123     if(tr[rt].l==l&&tr[rt].r==r)
    124     {
    125         num+=r-l+1-tr[rt].val;
    126         tr[rt].val=r-l+1;
    127         tr[rt].s=0;
    128         tr[rt].same=1;
    129         tr[rt].fir=l;
    130         tr[rt].las=r;
    131         return;
    132     }
    133     if(tr[rt].l==tr[rt].r)
    134         return ;
    135     Pushdown(rt);
    136     int L=rt<<1,R=rt<<1|1;
    137     if(l<=tr[L].r)
    138     {
    139         if(r<=tr[L].r)
    140             Update2(L,l,r);
    141         else
    142             Update2(L,l,tr[L].r);
    143     }
    144     if(r>=tr[R].l)
    145     {
    146         if(l>=tr[R].l)
    147             Update2(R,l,r);
    148         else
    149             Update2(R,tr[R].l,r);
    150     }
    151     Pushup(rt);
    152 }
    153 int sum(int rt,int l,int r)
    154 {
    155     if(tr[rt].l==l&&tr[rt].r==r)
    156     {
    157         return tr[rt].val;
    158     }
    159     int ans=0;
    160     Pushdown(rt);//因为只是查询,所以区间整体并没有变,就没有必要pushup了;
    161     int L=rt<<1,R=rt<<1|1;
    162     if(l<=tr[L].r)
    163     {
    164         if(r<=tr[L].r)
    165             ans+= sum(L,l,r);
    166         else
    167             ans+= sum(L,l,tr[L].r);
    168     }
    169     if(r>=tr[R].l)
    170     {
    171         if(l>=tr[R].l)
    172             ans+= sum(R,l,r);
    173         else
    174             ans+= sum(R,tr[R].l,r);
    175     }
    176     return ans;
    177 }
    178 int bisearch(int a,int f)
    179 {
    180     if(sum(1,a,n)==0)
    181         return -1;
    182     if(sum(1,a,n)<f)//此处的等于号的问题;
    183         return n;
    184     int l=a,r=n;
    185     int ans=a;
    186     while(l<=r)
    187     {
    188         int mid=(l+r)/2;
    189         if(sum(1,a,mid)>=f)//以及此处的等于号;
    190         {
    191             ans=mid;//这里ans的取值;
    192             r=mid-1;
    193         }
    194         else l=mid+1;
    195     }
    196     return ans;
    197 }
    198 int main()
    199 {
    200     int T;
    201     scanf("%d",&T);
    202     while(T--)
    203     {
    204         scanf("%d%d",&n,&m);
    205         build(1,1,n);
    206         for(int i=0;i<m;i++)
    207         {
    208             int ty,z,y;
    209             scanf("%d%d%d",&ty,&z,&y);
    210             if(ty==1)
    211             {
    212                 int t=bisearch(z+1,y);
    213                 if(t!=-1)
    214                 {
    215                     x=y;
    216                     first=0;
    217                     last=0;
    218                     Update1(1,z+1,t);
    219                     printf("%d %d
    ",first-1,last-1);
    220                 }
    221                 else 
    222                     printf("Can not put any one.
    ");
    223             }
    224             else 
    225             {
    226                 num=0;
    227                 Update2(1,z+1,y+1);
    228                 printf("%d
    ",num);
    229             }
    230         }
    231         printf("
    ");
    232     }
    233     return 0;
    234 }
  • 相关阅读:
    递归
    数据结构与算法-复杂度分析
    'latin-1' codec can't encode characters in position解决字符问题
    redis理解
    spring 嵌套事务问题
    Parameterized testing with any Python test framework
    分布式事务测试考虑点
    python orm / 表与model相互转换
    Python多线程、多进程
    JS运动
  • 原文地址:https://www.cnblogs.com/by-1075324834/p/4543002.html
Copyright © 2011-2022 走看看