• 约会安排 (连续区间 + lazy优先级)


    题目链接:https://vjudge.net/contest/332656#problem/I

    题目大意:

    小明需要安排和基友开黑和和女神约会的时间。这两个时间总是一段连续的时间,小明总是会找最早的时间来开始这些事。当有基友找他开黑的时候,他会先在时间表里找最早的连续时间,如果有,就开黑,没有就不开黑。当有女神和他约会,他先在时间表里找最早的连续时间,如果有就约会,没有他会先不考虑和基友开黑,先和女神约会,如果有时间就约会。

    思路:

    因为涉及到基友和女神,那线段树里就需要维护两种连续区间,分别为女神的和屌丝的,区间维护三个,左边最大连续区间,右边最大连续区间,和总的最大连续区间。下推标记有三个:学习,屌丝,女神。最容易错的地方是下推标记。当标记学习的时候,屌丝和女神标记应当还原,当标记女神的时候,屌丝标记也应当标记上(因为更新女神所占用的时间的时候,其实屌丝的时间也需要更新)

      1 #include <math.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <iostream>
      5 #include <algorithm>
      6 #include <string>
      7 #include <string.h>
      8 #include <vector>
      9 #include <map>
     10 #include <stack>
     11 #include <set>
     12 #include <random>
     13 
     14 #define ll long long
     15 #define ls nod<<1
     16 #define rs (nod<<1)+1
     17 const int maxn = 1e5 + 10;
     18 int n,m;
     19 
     20 struct segment_tree {
     21     int l,r;
     22     int n,d,s;
     23     int nsum,nls,nrs;
     24     int dsum,dls,drs;
     25 }tree[maxn<<2];
     26 
     27 void pushup(int nod) {
     28     tree[nod].dsum = std::max(std::max(tree[ls].dsum,tree[rs].dsum),tree[ls].drs+tree[rs].dls);
     29     tree[nod].dls = tree[ls].dls;
     30     tree[nod].drs = tree[rs].drs;
     31     if (tree[ls].dls == (tree[ls].r - tree[ls].l + 1))
     32         tree[nod].dls = tree[ls].dsum + tree[rs].dls;
     33     if (tree[rs].drs == (tree[rs].r - tree[rs].l + 1))
     34         tree[nod].drs = tree[rs].dsum + tree[ls].drs;
     35 
     36     tree[nod].nsum = std::max(std::max(tree[ls].nsum,tree[rs].nsum),tree[ls].nrs+tree[rs].nls);
     37     tree[nod].nls = tree[ls].nls;
     38     tree[nod].nrs = tree[rs].nrs;
     39     if (tree[ls].nls == (tree[ls].r - tree[ls].l + 1))
     40         tree[nod].nls = tree[ls].nsum + tree[rs].nls;
     41     if (tree[rs].nrs == (tree[rs].r - tree[rs].l + 1))
     42         tree[nod].nrs = tree[rs].nsum + tree[ls].nrs;
     43 }
     44 
     45 void pushdown(int nod) {
     46     if (tree[nod].s == 1) {
     47         tree[ls].dls = tree[ls].drs = tree[ls].dsum = (tree[ls].r - tree[ls].l + 1);
     48         tree[rs].dls = tree[rs].drs = tree[rs].dsum = (tree[rs].r - tree[rs].l + 1);
     49         tree[ls].nls = tree[ls].nrs = tree[ls].nsum = (tree[ls].r - tree[ls].l + 1);
     50         tree[rs].nls = tree[rs].nrs = tree[rs].nsum = (tree[rs].r - tree[rs].l + 1);
     51         tree[ls].s = tree[rs].s = tree[nod].s;
     52         tree[ls].n = tree[rs].n = -1;
     53         tree[ls].d = tree[rs].d = -1;
     54         tree[nod].s = -1;
     55     }
     56     if (tree[nod].n == 1) {
     57         tree[ls].nls = tree[ls].nrs = tree[ls].nsum = tree[rs].nls = tree[rs].nrs = tree[rs].nsum = 0;
     58         tree[ls].n = tree[rs].n = tree[nod].n;
     59         tree[nod].n = -1;
     60     }
     61     if (tree[nod].d == 1) {
     62         tree[ls].dls = tree[ls].drs = tree[ls].dsum = tree[rs].dls = tree[rs].drs = tree[rs].dsum = 0;
     63         tree[ls].d = tree[rs].d = tree[nod].d;
     64         tree[nod].d = -1;
     65     }
     66 }
     67 
     68 void build(int l,int r,int nod) {
     69     tree[nod].l = l;
     70     tree[nod].r = r;
     71     tree[nod].n = tree[nod].s = tree[nod].d = -1;
     72     tree[nod].dls = tree[nod].drs = tree[nod].dsum = (r - l + 1);
     73     tree[nod].nls = tree[nod].nrs = tree[nod].nsum = (r - l + 1);
     74     if (l == r)
     75         return ;
     76     int mid = (l + r ) >> 1;
     77     build(l,mid,ls);
     78     build(mid+1,r,rs);
     79 }
     80 
     81 void modify(int x,int y,int flag,int nod=1) {
     82     int l = tree[nod].l,r = tree[nod].r;
     83     if (x <= l && y >= r) {
     84         if (flag == 1) {
     85             tree[nod].nls = tree[nod].nrs = tree[nod].nsum = tree[nod].dls = tree[nod].drs = tree[nod].dsum = 0;
     86             tree[nod].n = 1;
     87             tree[nod].d = 1;
     88         }
     89         else {
     90             tree[nod].dls = tree[nod].drs = tree[nod].dsum = 0;
     91             tree[nod].d = 1;
     92         }
     93         return ;
     94     }
     95     pushdown(nod);
     96     int mid = (l + r) >> 1;
     97     if (x <= mid) {
     98         modify(x,y,flag,ls);
     99     }
    100     if (y > mid) {
    101         modify(x,y,flag,rs);
    102     }
    103     pushup(nod);
    104 }
    105 
    106 int queryD(int x,int nod=1) {
    107     int l = tree[nod].l,r = tree[nod].r;
    108     if (l == r)
    109         return l;
    110     pushdown(nod);
    111     if (x <= tree[ls].dsum) {
    112         return queryD(x,ls);
    113     }
    114     else if (tree[ls].drs + tree[rs].dls >= x) {
    115         return tree[ls].r - tree[ls].drs + 1;
    116     }
    117     else
    118         return queryD(x,rs);
    119 }
    120 
    121 int queryN(int x,int nod=1) {
    122     int l = tree[nod].l,r = tree[nod].r;
    123     if (l == r)
    124         return l;
    125     pushdown(nod);
    126     if (x <= tree[ls].nsum) {
    127         return queryN(x,ls);
    128     }
    129     else if (tree[ls].nrs + tree[rs].nls >= x) {
    130         return tree[ls].r - tree[ls].nrs + 1;
    131     }
    132     else
    133         return queryN(x,rs);
    134 }
    135 
    136 void clean(int x,int y,int nod=1) {
    137     int l = tree[nod].l,r = tree[nod].r;
    138     if (x <= l && y >= r) {
    139         tree[nod].dls = tree[nod].drs = tree[nod].dsum = tree[nod].nls = tree[nod].nrs = tree[nod].nsum = (r - l + 1);
    140         tree[nod].s = 1;
    141         tree[nod].n = -1;
    142         tree[nod].d = -1;
    143         return ;
    144     }
    145     pushdown(nod);
    146     int mid = (l + r) >> 1;
    147     if (x <= mid) {
    148         clean(x,y,ls);
    149     }
    150     if (y > mid) {
    151         clean(x,y,rs);
    152     }
    153     pushup(nod);
    154 }
    155 
    156 int main() {
    157     int Case;
    158     int t = 1;
    159     scanf("%d",&Case);
    160     while (Case--) {
    161         scanf("%d%d",&n,&m);
    162         build(1,n,1);
    163         printf("Case %d:
    ",t++);
    164         while (m--) {
    165             int num,x,y;
    166             char str[10];
    167             scanf("%s",str);
    168             if (str[0] == 'D') {
    169                 scanf("%d",&num);
    170                 if (tree[1].dsum < num) {
    171                     printf("fly with yourself
    ");
    172                 }
    173                 else {
    174                     int ans = queryD(num);
    175                     printf("%d,let's fly
    ",ans);
    176                     modify(ans,ans+num-1,2);
    177                 }
    178             }
    179             else if (str[0] == 'N') {
    180                 scanf("%d",&num);
    181                 if (tree[1].nsum < num) {
    182                     printf("wait for me
    ");
    183                 }
    184                 else {
    185                     if (tree[1].dsum >= num) {
    186                         int ans = queryD(num);
    187                         printf("%d,don't put my gezi
    ",ans);
    188                         modify(ans,ans+num-1,1);
    189                     }
    190                     else if (tree[1].nsum >= num) {
    191                         int ans = queryN(num);
    192                         printf("%d,don't put my gezi
    ",ans);
    193                         modify(ans,ans+num-1,1);
    194                     }
    195                 }
    196             }
    197             else {
    198                 scanf("%d%d",&x,&y);
    199                 clean(x,y,1);
    200                 printf("I am the hope of chinese chengxuyuan!!
    ");
    201             }
    202         }
    203     }
    204     return 0;
    205 }
  • 相关阅读:
    225. 用队列实现栈
    232. 用栈实现队列
    459.重复的子字符串(简单)
    28. 实现 strStr()(简单)
    剑指 Offer 58
    541. 反转字符串 II(简单)
    浏览器渲染页面的过程、重绘、重排以及页面优化
    隐藏一个元素的几种方法
    当我们在浏览器中输入一个URL后,发生了什么?
    Object.create() 和 new Object()、{} 的区别
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11729306.html
Copyright © 2020-2023  润新知