zoukankan      html  css  js  c++  java
  • HDU 4614 Vases and Flowers(线段树+记录区间始末点或乱搞)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614

    题目大意:有n个空花瓶,有两种操作:

         操作①:给出两个数字A,B,表示从第A个花瓶开始插花,插B朵花,输出第一个和最后一个插入的花瓶,如果任意花瓶都已经满了不能插花,则输出“Can not put any one.”。

         操作②:给出两个数字A,B,表示清空第A~B个花瓶,并输出清空掉的花朵数目。

    解题思路:线段树,关于操作②,很简单弄个sum表示区间空花瓶数,计算时清空掉的花朵数=区间长度-sum。

         关于操作①,有两种解法,第一种就是记录更新每个区间的空花瓶的始末点,这样在插花时可以由此直接获得起点终点。

               第二种,就是乱搞,查找全空区间(都是空花瓶)然后插花,全空区间起点终点的获得就不用说了吧。复杂度真的是玄学(感觉完全算不出来),还以为会超时的,竟然比解法一还快点。。。

    解法一:

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #define LC(a) ((a<<1))
      4 #define RC(a) ((a<<1)+1)
      5 #define MID(a,b) ((a+b)>>1)
      6 using namespace std;
      7 typedef long long ll;
      8 const int N = 5e4 + 5;
      9 
     10 struct node {
     11     ll l, r;
     12     ll sum, Start, End, color;//Start是第一个空花瓶位置,End是最后一个空花瓶位置,color=-1,0,1代表初始化,清空,插花 
     13 }tree[N<<2];
     14 
     15 ll leave, Start, sum, End;
     16 void pushup(ll p) {
     17     //维护区间空花瓶数量 
     18     tree[p].sum = tree[LC(p)].sum + tree[RC(p)].sum;
     19     tree[p].color = (tree[LC(p)].color == tree[RC(p)].color ? tree[LC(p)].color : -1);
     20     //维护空花瓶起点和终点 
     21     if (tree[LC(p)].Start != 0)
     22         tree[p].Start = tree[LC(p)].Start;
     23     else if (tree[LC(p)].End != 0)
     24         tree[p].Start = tree[LC(p)].End;
     25     else if (tree[RC(p)].Start != 0)
     26         tree[p].Start = tree[RC(p)].Start;
     27     else if (tree[RC(p)].End != 0)
     28         tree[p].Start = tree[RC(p)].End;
     29     else
     30         tree[p].Start = 0;
     31     tree[p].End = max(max(tree[LC(p)].Start, tree[LC(p)].End), max(tree[RC(p)].Start, tree[RC(p)].End));
     32 }
     33 
     34 void pushdown(ll p) {
     35     if (tree[p].color == 0) {
     36         tree[LC(p)].sum = tree[LC(p)].r - tree[LC(p)].l + 1;
     37         tree[LC(p)].Start = tree[LC(p)].l;
     38         tree[LC(p)].End = tree[LC(p)].r;
     39         tree[RC(p)].sum = tree[RC(p)].r - tree[RC(p)].l + 1;
     40         tree[RC(p)].Start = tree[RC(p)].l;
     41         tree[RC(p)].End = tree[RC(p)].r;
     42         tree[LC(p)].color = tree[RC(p)].color = 0;
     43     }
     44     else if (tree[p].color == 1) {
     45         tree[LC(p)].sum = tree[LC(p)].Start = tree[LC(p)].End = tree[RC(p)].sum = tree[RC(p)].Start = tree[RC(p)].End = 0;
     46         tree[LC(p)].color = tree[RC(p)].color = 1;
     47     }
     48 }
     49  
     50 void build(ll p, ll l, ll r) {
     51     tree[p].l = l;
     52     tree[p].r = r;
     53     tree[p].Start = tree[p].End = 0;
     54     tree[p].sum = 0;
     55     if (l == r) {
     56         tree[p].Start = tree[p].End = l;
     57         tree[p].sum = 1;
     58         tree[p].color = -1;
     59         return;
     60     }
     61     build(LC(p), l, MID(l, r));
     62     build(RC(p), MID(l, r) + 1, r);
     63     pushup(p);
     64 }
     65 //清空 
     66 void update(ll p, ll l, ll r) {
     67     if (r<tree[p].l || l>tree[p].r)
     68         return;
     69     if (l <= tree[p].l&&r >= tree[p].r) {
     70         sum += (tree[p].r - tree[p].l + 1 - tree[p].sum);
     71         tree[p].Start = tree[p].l;
     72         tree[p].End = tree[p].r;
     73         tree[p].sum = tree[p].r - tree[p].l + 1;
     74         tree[p].color = 0;
     75         return;
     76     }
     77     pushdown(p);
     78     update(LC(p), l, r);
     79     update(RC(p), l, r);
     80     pushup(p);
     81 }
     82 //插花 
     83 void query(ll p, ll l, ll r) {
     84     if (r<tree[p].l || l>tree[p].r)
     85         return;
     86     if (leave == 0 || tree[p].sum == 0)
     87         return;
     88     if (l <= tree[p].l&&r >= tree[p].r) {
     89         if (Start == 0)
     90             Start = tree[p].Start;
     91         if (leave >= tree[p].sum) {
     92             leave -= tree[p].sum;
     93             End = max(End, tree[p].End);
     94             tree[p].sum = tree[p].Start = tree[p].End = 0;
     95             tree[p].color = 1;
     96             return;
     97         }
     98     }
     99     pushdown(p);
    100     query(LC(p), l, r);
    101     query(RC(p), l, r);
    102     pushup(p);
    103 }
    104 int main() {
    105     ll q;
    106     scanf("%I64d",&q);
    107     while (q--) {
    108         ll n, m;
    109         scanf("%I64d %I64d",&n,&m);
    110         build(1, 1, n);
    111         while (m--) {
    112             ll k;
    113             scanf("%I64d",&k);
    114             //插花 
    115             if (k == 1) {
    116                 ll a, f;
    117                 scanf("%I64d %I64d",&a,&f);
    118                 End = Start = 0;
    119                 leave = f;
    120                 query(1, a + 1, n);
    121                 if (Start == 0)
    122                     printf("Can not put any one.
    ");
    123                 else
    124                     printf("%I64d %I64d
    ",Start-1,End-1);
    125             }
    126             //清空 
    127             else {
    128                 ll a, b;
    129                 scanf("%I64d %I64d",&a,&b);
    130                 sum = 0;
    131                 update(1, a + 1, b + 1);
    132                 printf("%I64d
    ",sum);
    133             }
    134         }
    135         printf("
    ");
    136     }
    137     return 0;
    138 }

    解法二:

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<vector>
      7 #include<queue>
      8 #include<set>
      9 #include<map>
     10 #include<string>
     11 #define LC(a) (a<<1)
     12 #define RC(a) (a<<1|1)
     13 #define MID(a,b) ((a+b)>>1)
     14 using namespace std;
     15 typedef long long LL;
     16 const int INF=0x3f3f3f3f;
     17 const int N=5e4+5;
     18 
     19 int ans,x,Start,End,flag;
     20 
     21 struct node{
     22     int sum,l,r;//sum表示空花瓶数 
     23 }tree[4*N];
     24 
     25 void pushdown(int p){
     26     //全满 
     27     if(tree[p].sum==tree[p].r-tree[p].l+1){
     28         tree[LC(p)].sum=tree[LC(p)].r-tree[LC(p)].l+1;
     29         tree[RC(p)].sum=tree[RC(p)].r-tree[RC(p)].l+1;
     30     }
     31     //全空 
     32     else if(tree[p].sum==0)
     33         tree[LC(p)].sum=tree[RC(p)].sum=0;
     34 }
     35 
     36 void pushup(int p){
     37     tree[p].sum=tree[LC(p)].sum+tree[RC(p)].sum;
     38 }
     39 
     40 void build(int p,int l,int r){
     41     tree[p].l=l;
     42     tree[p].r=r;
     43     if(l==r){
     44         tree[p].sum=1;
     45         return;
     46     }
     47     build(LC(p),l,MID(l,r));
     48     build(RC(p),MID(l,r)+1,r);
     49     pushup(p);
     50 }
     51 
     52 void update(int p,int l,int r){
     53     if(l>tree[p].r||r<tree[p].l)
     54         return;
     55     if(x<=0)
     56         return;    
     57     if(l<=tree[p].l&&r>=tree[p].r){
     58         if(tree[p].sum==0)
     59             return;
     60         //找到全空区间 
     61         if(x>=tree[p].sum&&tree[p].sum==tree[p].r-tree[p].l+1){
     62             if(flag==0){
     63                 Start=tree[p].l;
     64                 flag++;
     65             }
     66             x-=tree[p].sum;
     67             tree[p].sum=0;    
     68             End=tree[p].r;
     69             return;
     70         }
     71     }
     72     pushdown(p);
     73     update(LC(p),l,r);
     74     update(RC(p),l,r);
     75     pushup(p);
     76 }
     77 
     78 void query(int p,int l,int r){
     79     if(l>tree[p].r||r<tree[p].l)
     80         return;
     81     if(l<=tree[p].l&&r>=tree[p].r){
     82         ans+=tree[p].r-tree[p].l+1-tree[p].sum;
     83         tree[p].sum=tree[p].r-tree[p].l+1;
     84         return;
     85     }
     86     pushdown(p);
     87     query(LC(p),l,r);
     88     query(RC(p),l,r);
     89     pushup(p);
     90 }
     91 
     92 int main(){
     93     int T;
     94     scanf("%d",&T);
     95     while(T--){
     96         int n,q;
     97         scanf("%d%d",&n,&q);
     98         build(1,0,n-1);
     99         while(q--){
    100             int op;
    101             scanf("%d",&op);
    102             if(op==1){
    103                 int l;
    104                 scanf("%d%d",&l,&x);
    105                 flag=0;
    106                 update(1,l,n-1);
    107                 if(flag==0)
    108                     printf("Can not put any one.
    ");
    109                 else
    110                     printf("%d %d
    ",Start,End);
    111             }
    112             else{
    113                 int l,r;
    114                 scanf("%d%d",&l,&r);
    115                 ans=0;
    116                 query(1,l,r);
    117                 printf("%d
    ",ans);
    118             } 
    119         }
    120         printf("
    ");
    121     }
    122     return 0;
    123 }
  • 相关阅读:
    递归的用法
    冒泡排序
    Python_MySQL:MySQL常用命令
    开发Python项目案例,这8个库不容错过,功能强大性能优质
    pyQuery CSS选择器
    数据结构——快速排序(使用Java)
    spring security 动态配置登出页面
    String、StringBuffer和StringBuilder
    vue部署项目刷新404的解决方案
    String数组常用的几种遍历方法
  • 原文地址:https://www.cnblogs.com/fu3638/p/7604066.html
Copyright © 2011-2022 走看看