zoukankan      html  css  js  c++  java
  • BZOJ 4341 [CF253 Printer] 解题报告

    乍一看这个题好像可以二分优先度搞搞。。。

    实际上能不能这么搞呢。。。?

    我反正不会。。。

    于是开始讲我的乱搞算法:

    首先肯定要把任务按照优先度排序。

    用一棵在线建点的线段树维护一个时刻是否在工作。

    然后就依次插入任务,记为 i,具体而言就是二分其右端点,然后令这整个区间都变成 “工作” 的状态。

    在 i 被插入之前,还要检验一下在当前情况那个神秘任务的右端点是不是题中所要求的那个。

    如果是,并且 i-1 的优先度和 i 的优先度不相邻或者 i 就是最优先的任务,那么就令那个神秘任务的优先度为 i 的优先度+1。

    然后把这个神秘任务插入,再来考虑任务 i。

    这么写完之后发现超时了。一个点要跑 2.5s 左右。

    实际上到了后面,超过 10^9 的时间是一段 1,然后才是 0。

    所以这里我们只需维护这个分界点就可以了。

    线段树的上界就从 10^15 变成了 10^9,比原来快了一倍。

    于是就可以 AC 了。

      1 #include <cstdio>
      2 #include <algorithm>
      3 using namespace std;
      4 typedef long long LL;
      5 const int N = 50000 + 5;
      6 const int M = 15000000 + 5;
      7 const int T = 1000000000;
      8  
      9 int n, root, tot, ans_p;
     10 LL end, Tend = T, owari, Ans[N];
     11  
     12 struct Segment_Tree
     13 {
     14     int l, r, sum;
     15 }h[M];
     16  
     17 struct Task
     18 {
     19     int s, t, p, id;
     20     Task (int _s = 0, int _t = 0, int _p = 0, int _id = 0) {s = _s, t = _t, p = _p, id = _id;}
     21     bool operator < (const Task a) const
     22     {
     23         return p > a.p;
     24     }
     25 }P[N];
     26  
     27 inline void Modify(int &x, int l, int r, int s, int t)
     28 {
     29     if (!x) x = ++ tot;
     30     if (l == s && r == t) h[x].sum = r - l + 1;
     31     if (h[x].sum == r - l + 1) return ;
     32     LL mid = l + r >> 1;
     33     if (t <= mid) Modify(h[x].l, l, mid, s, t);
     34         else if (s > mid) Modify(h[x].r, mid + 1, r, s, t);
     35         else Modify(h[x].l, l, mid, s, mid), Modify(h[x].r, mid + 1, r, mid + 1, t);
     36     h[x].sum = h[h[x].l].sum + h[h[x].r].sum;
     37 }
     38  
     39 inline LL Query(int x, int l, int r, int s, int t)
     40 {
     41     if (!x) return 0;
     42     if (h[x].sum == r - l + 1) return t - s + 1;
     43     if (l == s && r == t) return h[x].sum;
     44     LL mid = l + r >> 1;
     45     if (t <= mid) return Query(h[x].l, l, mid, s, t);
     46         else if (s > mid) return Query(h[x].r, mid + 1, r, s, t);
     47         else return Query(h[x].l, l, mid, s, mid) + Query(h[x].r, mid + 1, r, mid + 1, t);
     48 }
     49  
     50 inline LL Calc(Task x)
     51 {
     52     int need = x.t;
     53     int blank = T - x.s + 1 - Query(1, 0, T, x.s, T);
     54     if (blank < need) return need - blank + Tend;
     55     int l = x.s, r = T;
     56     while (l < r)
     57     {
     58         int mid = l + r >> 1;
     59         blank = mid - x.s + 1 - Query(1, 0, T, x.s, mid);
     60         if (blank < need) l = mid + 1;
     61             else r = mid;
     62     }
     63     return l;
     64 }
     65  
     66 int main()
     67 {
     68     scanf("%d", &n);
     69     for (int i = 1; i <= n; i ++)
     70     {
     71         int s, t, p;
     72         scanf("%d%d%d", &s, &t, &p);
     73         if (p == -1) p = 0;
     74         P[i] = Task(s, t, p, i);
     75     }
     76     sort(P + 1, P + n + 1);
     77     scanf("%lld", &end);
     78     Ans[P[n].id] = end;
     79     for (int i = 1; i <= n; i ++)
     80     {
     81         if (ans_p) goto deal;
     82         owari = Calc(P[n]);
     83         if (owari + 1 == end && (i == 1 || P[i].p != P[i - 1].p - 1))
     84         {
     85             ans_p = P[i].p + 1;
     86             Modify(root, 0, T, P[n].s, owari < T ? owari : T);
     87             Tend = Tend > owari ? Tend : owari;
     88         }
     89          
     90         deal :;
     91         if (i == n) continue ;
     92         owari = Calc(P[i]);
     93         Modify(root, 0, T, P[i].s, owari < T ? owari : T);
     94         Tend = Tend > owari ? Tend : owari;
     95         Ans[P[i].id] = owari + 1;
     96     }
     97     printf("%d
    ", ans_p);
     98     for (int i = 1; i <= n; i ++)
     99         printf("%lld%c", Ans[i], i == n ? '
    ' : ' ');
    100      
    101     return 0;
    102 }
    4341_Gromah
  • 相关阅读:
    详细解析Windows按键突破专家的原理
    详细解析Windows按键突破专家的原理
    简单线程注入的实现
    运用 Evince 阅读 PDF 电子书
    Sonata 0.7
    P7ZIP-Linux 中的 7Zip
    Firefox 特征扩展:Video Download
    若何在嵌入式Linux及下建造QPF字库
    Wink-Flash 演示录制软件
    自由软件:理想与实践
  • 原文地址:https://www.cnblogs.com/gromah/p/5005607.html
Copyright © 2011-2022 走看看