• hdu 4614 [简单线段树+二分查找]


    // hdu 4614

    // 题意 机器翻译 爱丽丝非常受欢迎,每天都能收到很多花。她有N个花瓶,编号从0到N-1。当她收到几朵花时,她会尝试将它们放在花瓶中,一朵花放在一个花瓶中。她随机选择花瓶A,并尝试在花瓶中放一朵花。如果花瓶中没有花,她会在上面放一朵花,否则她会跳过这个花瓶。然后她将尝试放入花瓶A + 1,A + 2,...,N-1,直到没有花了,或者她尝试了花瓶N-1。剩下的花将被丢弃。当然,有时她会清洗花瓶。由于花瓶过多,她随机选择清洗编号从A到B(A <= B)的花瓶。清洗过的花瓶中的花将被丢弃。

    第一行包含一个整数T,表示测试用例的数量。

      对于每个测试用例,第一行包含两个整数N(1 <N <50001)和M(1 <M <50001)。N是花瓶的数量,M是爱丽丝的业务。接下来的M行中的每行包含三个整数。一行的第一个整数是K(1或2)。如果K为1,则跟随两个整数A和F。这意味着爱丽丝会收到F朵花,然后尝试先在花瓶A中放一朵花。如果K为2,则跟随两个整数A和B。这意味着所有者希望清洗编号从A到B(A <= B)的花瓶。
      对于K为1的每个操作,输出花瓶的位置,爱丽丝将第一朵花和最后一朵花放在花瓶中,并用空格隔开。如果她不能放任何东西,则输出“不能放任何东西”。对于K为2的每个操作,输出丢弃的花朵数量。
      1 /*
      2  * @Promlem: hdu 4614
      3  * @Time Limit: 2000ms
      4  * @Memory Limit: 32768k
      5  * @Author: pupil-XJ
      6  * @Date: 2019-10-12 14:11:16
      7  * @LastEditTime: 2019-10-13 01:03:11
      8  */
      9 #include<cstdio>
     10 #include<algorithm>
     11 #define L k<<1
     12 #define R k<<1|1
     13 #define mid (tree[k].l+tree[k].r)>>1
     14 using namespace std;
     15 const int MAXN = 50000+5;
     16 
     17 struct segmemt_tree {
     18     int l, r;
     19     int num, f;
     20 } tree[4*MAXN+1];
     21 
     22 inline void build(int k, int l, int r) {
     23     tree[k].l = l; tree[k].r = r;
     24     tree[k].num = 0;
     25     tree[k].f = -1;
     26     if(l == r) return ;
     27     int m = mid;
     28     build(L, l, m);
     29     build(R, m+1, r);
     30 }
     31 
     32 inline void push_down(int k) {
     33     tree[L].f = tree[R].f = tree[k].f;
     34     int m = mid;
     35     tree[L].num = (m-tree[k].l+1) * tree[k].f;
     36     tree[R].num = (tree[k].r-m) * tree[k].f;
     37     tree[k].f = -1;
     38 }
     39 
     40 inline int query(int k, int x, int y) {// 查询区间内插入花的数量
     41     if(tree[k].l >= x && tree[k].r <= y) return tree[k].num;
     42     if(tree[k].f != -1) push_down(k);
     43     int m = mid;
     44     int ans = 0;
     45     if(x <= m) ans = query(L, x, y);
     46     if(y > m) ans += query(R, x, y);
     47     return ans;
     48 }
     49 
     50 inline int bin(int start, int end, int cnt) {// 二分查找 l=start 到 r=end 第cnt个空花瓶
     51     int l = start, r = end;
     52     while(l < r) {
     53         int m = (l + r) / 2;
     54         int t = (m - start + 1) - query(1, start, m);
     55         if(t >= cnt) r = m;
     56         else l = m + 1;
     57     }
     58     return l;
     59 }
     60 
     61 inline void change(int k, int x, int y, int v) {
     62     if(tree[k].l >= x && tree[k].r <= y) {
     63         tree[k].f = v;
     64         tree[k].num = (tree[k].r - tree[k].l + 1) * v;
     65         return ;
     66     }
     67     if(tree[k].f != -1) push_down(k);
     68     int m = mid;
     69     if(x <= m) change(L, x, y, v);
     70     if(y > m) change(R, x, y, v);
     71     tree[k].num = tree[L].num + tree[R].num;
     72 }
     73 
     74 int main() {
     75     int T;
     76     scanf("%d", &T);
     77     while(T--) {
     78         int n, m;
     79         scanf("%d%d", &n, &m);
     80         build(1, 0, n-1);
     81         int op, x, y;
     82         int s, e;
     83         for(int i = 0; i != m; ++i) {
     84             scanf("%d%d%d", &op, &x, &y);
     85             if(op == 1) {
     86                 int one = query(1, x, n-1);
     87                 if(one == n-1-x+1) printf("Can not put any one.
    ");
     88                 else {
     89                     s = bin(x, n-1, 1);// 第一个空花瓶位置
     90                     e = bin(s, n-1, min(n-1-x+1-one, y));// 最后一个空花瓶位置
     91                     printf("%d %d
    ", s, e);
     92                     change(1, s, e, 1);
     93                 }
     94             }
     95             else printf("%d
    ", query(1, x, y)), change(1, x, y, 0);
     96         }
     97         printf("
    ");
     98     }
     99     return 0;
    100 }

    附上一个很蠢的代码 TLE

     1 /*
     2  * @Promlem: 
     3  * @Time Limit: ms
     4  * @Memory Limit: k
     5  * @Author: pupil-XJ
     6  * @Date: 2019-10-12 14:11:16
     7  * @LastEditTime: 2019-10-12 22:58:36
     8  */
     9 #include<cstdio>
    10 #define L k<<1
    11 #define R k<<1|1
    12 #define mid (tree[k].l+tree[k].r)>>1
    13 using namespace std;
    14 const int MAXN = 50000+4;
    15 
    16 struct segmemt_tree {
    17     int l, r, num;
    18     int f;
    19 } tree[4*MAXN+1];
    20 
    21 void build(int k, int l, int r) {
    22     tree[k].l = l; tree[k].r = r;
    23     tree[k].num = 0;
    24     tree[k].f = 0;
    25     if(l == r) return ;
    26     int m = mid;
    27     build(L, l, m);
    28     build(R, m+1, r);
    29 }
    30 
    31 void down(int k) {
    32     tree[L].num = tree[R].num = 0;
    33     tree[L].f = tree[R].f = 1;
    34     tree[k].f = 0;
    35 }
    36 
    37 int sx, ex, sum;
    38 void update(int k, int x, int y, int op) {
    39     if(op == 1 && !sum) return ;
    40     // if(tree[k].num == tree[k].r-tree[k].l+1) return ;
    41     if(tree[k].l >= x && tree[k].r <= y) {
    42         if(tree[k].f) down(k);
    43         if(op == 0) {
    44             tree[k].f = 1;
    45             sum += tree[k].num;
    46             tree[k].num = 0;
    47         }
    48         else if(tree[k].l == tree[k].r) {
    49             if(tree[k].num == 0) {
    50                 tree[k].num = 1;
    51                 if(sx == -1) sx = ex = tree[k].l;
    52                 else ex = tree[k].l;
    53                 --sum;
    54             }
    55         }
    56         else {
    57             int m = mid;
    58             if(x <= x) update(L, x, y, op);
    59             if(y > m) update(R, x, y, op);
    60             tree[k].num = tree[L].num + tree[R].num;
    61         }
    62         return ;
    63     }
    64     if(tree[k].f) down(k);
    65     int m = mid;
    66     if(x <= m) update(L, x, y, op);
    67     if(y > m) update(R, x, y, op);
    68     tree[k].num = tree[L].num + tree[R].num;
    69 }
    70 
    71 int main() {
    72     int T;
    73     scanf("%d", &T);
    74     while(T--) {
    75         int n, m;
    76         scanf("%d%d", &n, &m);
    77         build(1, 0, n-1);
    78         int op, x, y;
    79         for(int i = 0; i != m; ++i) {
    80             scanf("%d%d%d", &op, &x, &y);
    81             if(op == 1) {
    82                 sx = ex = -1;
    83                 sum = y;
    84                 update(1, x, n-1, 1);
    85                 if(ex == -1) printf("Can not put any one.
    ");
    86                 else printf("%d %d
    ", sx, ex);
    87             }
    88             else sum = 0, update(1, x, y, 0), printf("%d
    ", sum);
    89         }
    90         printf("
    ");
    91     }
    92     return 0;
    93 }
    TLE
  • 相关阅读:
    PEM_密钥对生成与读取方法
    RandomStringUtils RandomUtils
    Java高级个人笔记(RandomStringUtils工具类)
    如何让eclipse输出结果的console栏自动换行?
    日志框架logj的使用
    IDEA中Git的更新、提交、还原方法
    AWS核心服务概览
    技术资料的几种读法
    李笑来老师在《把时间当作朋友》曾说过:“所有学习上的成功,都只靠两件事:策略和坚持,而坚持本身就应该是最重要的策略之一
    ubuntu如何修改terminal终端的主机名(修改/etc/hostname文件)
  • 原文地址:https://www.cnblogs.com/pupil-xj/p/11664604.html
Copyright © 2020-2023  润新知