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

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

我反正不会。。。

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

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

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

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

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

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

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

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

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

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

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

于是就可以 AC 了。

 #include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = + ;
const int M = + ;
const int T = ; int n, root, tot, ans_p;
LL end, Tend = T, owari, Ans[N]; struct Segment_Tree
{
int l, r, sum;
}h[M]; struct Task
{
int s, t, p, id;
Task (int _s = , int _t = , int _p = , int _id = ) {s = _s, t = _t, p = _p, id = _id;}
bool operator < (const Task a) const
{
return p > a.p;
}
}P[N]; inline void Modify(int &x, int l, int r, int s, int t)
{
if (!x) x = ++ tot;
if (l == s && r == t) h[x].sum = r - l + ;
if (h[x].sum == r - l + ) return ;
LL mid = l + r >> ;
if (t <= mid) Modify(h[x].l, l, mid, s, t);
else if (s > mid) Modify(h[x].r, mid + , r, s, t);
else Modify(h[x].l, l, mid, s, mid), Modify(h[x].r, mid + , r, mid + , t);
h[x].sum = h[h[x].l].sum + h[h[x].r].sum;
} inline LL Query(int x, int l, int r, int s, int t)
{
if (!x) return ;
if (h[x].sum == r - l + ) return t - s + ;
if (l == s && r == t) return h[x].sum;
LL mid = l + r >> ;
if (t <= mid) return Query(h[x].l, l, mid, s, t);
else if (s > mid) return Query(h[x].r, mid + , r, s, t);
else return Query(h[x].l, l, mid, s, mid) + Query(h[x].r, mid + , r, mid + , t);
} inline LL Calc(Task x)
{
int need = x.t;
int blank = T - x.s + - Query(, , T, x.s, T);
if (blank < need) return need - blank + Tend;
int l = x.s, r = T;
while (l < r)
{
int mid = l + r >> ;
blank = mid - x.s + - Query(, , T, x.s, mid);
if (blank < need) l = mid + ;
else r = mid;
}
return l;
} int main()
{
scanf("%d", &n);
for (int i = ; i <= n; i ++)
{
int s, t, p;
scanf("%d%d%d", &s, &t, &p);
if (p == -) p = ;
P[i] = Task(s, t, p, i);
}
sort(P + , P + n + );
scanf("%lld", &end);
Ans[P[n].id] = end;
for (int i = ; i <= n; i ++)
{
if (ans_p) goto deal;
owari = Calc(P[n]);
if (owari + == end && (i == || P[i].p != P[i - ].p - ))
{
ans_p = P[i].p + ;
Modify(root, , T, P[n].s, owari < T ? owari : T);
Tend = Tend > owari ? Tend : owari;
} deal :;
if (i == n) continue ;
owari = Calc(P[i]);
Modify(root, , T, P[i].s, owari < T ? owari : T);
Tend = Tend > owari ? Tend : owari;
Ans[P[i].id] = owari + ;
}
printf("%d\n", ans_p);
for (int i = ; i <= n; i ++)
printf("%lld%c", Ans[i], i == n ? '\n' : ' '); return ;
}

4341_Gromah

BZOJ 4341 [CF253 Printer] 解题报告的更多相关文章

  1. BZOJ 4619 Swap Space 解题报告

    今天是因为David Lee正好讲这个题的类似题,我才做了一下. 本题是world final 2016的一道水…… 题目地址如下 http://www.lydsy.com/JudgeOnline/p ...

  2. BZOJ 2839: 集合计数 解题报告

    BZOJ 2839: 集合计数 Description 一个有\(N\)个元素的集合有\(2^N\)个不同子集(包含空集),现在要在这\(2^N\)个集合中取出若干集合(至少一个),使得 它们的交集的 ...

  3. BZOJ 1367 [Baltic2004]sequence 解题报告

    BZOJ 1367 [Baltic2004]sequence Description 给定一个序列\(t_1,t_2,\dots,t_N\),求一个递增序列\(z_1<z_2<\dots& ...

  4. BZOJ 1044 木棍分割 解题报告(二分+DP)

    来到机房刷了一道水(bian’tai)题.题目思想非常简单易懂(我的做法实际上参考了Evensgn 范学长,在此多谢范学长了) 题目摆上: 1044: [HAOI2008]木棍分割 Time Limi ...

  5. BZOJ 4036 [HAOI2015] Set 解题报告

    首先我们不能一位一位的考虑,为什么呢? 你想想,你如果一位一位地考虑的话,那么最后就只有 $n$ 个数字,然而他给了你 $2^n$ 个数字,怎么看都不对劲呀.(我是因为这样子弄没过样例才明白的) 所以 ...

  6. BZOJ 3288 Mato矩阵 解题报告

    这个题好神呀..Orz taorunz 有一个结论,这个结论感觉很优美: $$ans = \prod_{i=1}^{n}\varphi(i)$$ 至于为什么呢,大概是这样子的: 对于每个数字 $x$, ...

  7. BZOJ 4123 [Baltic2015] Hacker 解题报告

    首先,Alice 会选择一个长度为 $\lfloor\frac{n+1}{2}\rfloor$ 的区间,我们把这个长度记为 $len$. 有这么一个结论:令 $F_i$ 为覆盖 $i$ 点的所有长度为 ...

  8. BZOJ 4146 [AMPPZ2014] Divisors 解题报告

    这个题感觉比较小清新... 我们记录每个数出现的次数 $T_i$. 首先依次枚举每个数字,令 $ans = ans + T_i \times (T_i - 1)$,然后枚举这个数的倍数,令 $ans ...

  9. BZOJ 3971 Матрёшка 解题报告

    很自然想到区间 DP. 设 $Dp[i][j]$ 表示把区间 $[i, j]$ 内的套娃合并成一个所需要的代价,那么有: $Dp[i][i] = 0$ $Dp[i][j] = min\{Dp[i][k ...

随机推荐

  1. Oracle 联合主键

    alter table NCJSYD add constraints NCJSYD_pk primary key (YR,DQ);

  2. OSI参考模型

    1.物理层:发送和接收比特.(工作在物理层的集线器) 2.数据链路层:提供数据的物理传输,并处理错误通知.网络拓扑和流浪控制, 数据链路层将报文封装成数据帧,并添加定制的报头,其中包括目标硬件地址, ...

  3. [javascript|基本概念|Underfined]学习笔记

    Underfined类型的值:underfined(只有一个) 1/声明未初始化 e.g.:var msg;-->msg == underfined:true 2/申明并值初始化为underfi ...

  4. 对match() 和 exec() 返回值和属性的测试

    语法: exec() : RegExpObject.exec(string) match() : stringObject.match(string) stringObject.match(regex ...

  5. 4月13日学习笔记——jQuery工具函数

    浏览器及特性检测 jQuery.support.boxModel 如果这个页面和浏览器是以 W3C CSS 盒式模型来渲染的,则等于 true.通常在 IE 6 和 IE 7 的怪癖模式中这个值是 f ...

  6. linux exec函数族

    1.简介 在Linux中,并不存在exec()函数,exec指的是一组函数,一共有6个,分别是: #include <unistd.h>   extern char **environ; ...

  7. LLVM language 参考手册(译)(4)

    函数(Functions) LLVM函数定义由“define” 关键字,一个可选的链接标识,一个可选的可见性模式,一个可选的DLL存储类别,一个可选的调用约定,一个可选的 unnamed_addr 属 ...

  8. Log4Net总结

    Log4Net是用来记录日志的,可以将程序运行过程中的信息输出到一些地方(文件.数据库.EventLog等),日志就是程序的黑匣子,可以通过日志查看系统的运行过程,从而发现系统的问题.日志的作用:将运 ...

  9. mysql快速上手2

    上一篇文章讲的是mysql的基本操作,这一篇会有一点难以理解,本节主要内容mysql视图,存储过程,函数,事务,触发器,以及动态执行sql 视图view 视图是一个虚拟表,其内容由查询定义.同真实的表 ...

  10. 用户不在sudoers文件中的解决方法

    1.更改/etc/sudoers权限为777 2.修改文件中 root    ALL=(ALL)       ALL 下方增加 user    ALL=(ALL)       ALL 3.回复文件/e ...