记录编号 193060 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2012]借教室 最终得分 100
用户昵称 Gravatar啊吧啦吧啦吧 是否通过 通过
代码语言 C++ 运行时间 2.132 s
提交时间 2015-10-13 19:40:14 内存使用 19.37 MiB
显示代码纯文本
  1. /*用某一天的前缀和表示该天需要的教室数
  2. 比如一开始数列a是0 0 0 0 0 0
  3. 前缀和0 0 0 0 0 0
  4. 3到5天需要2的教室
  5. 将a[3]+=2,a[6]-=2
  6. 数列变为0 0 2 0 0 -2
  7. 前缀和变为0 0 2 2 2 0
  8. 这样就实现了增加3-5需要的教室数
  9. 然后我们二分订单数
  10. 处理前mid个订单看看是否有某一天的前缀和大于di*/
  11. #include <cstdio>
  12. #include <cctype>
  13. #include <algorithm>
  14. template <class T>
  15. T qread(T &x){
  16. x = 0;
  17. char c;
  18. while (! isdigit(c = getchar()));
  19. while (isdigit(c)){
  20. x = x * 10 + c - '0';
  21. c = getchar();
  22. }
  23. return x;
  24. }
  25. const int MAX(1000010);
  26. inline bool ok(int);
  27. int n, m, r[MAX], d[MAX], s[MAX], t[MAX], ans = 0, sum, ss[MAX];
  28. main()
  29. {
  30. freopen("classrooms.in", "r", stdin);
  31. freopen("classrooms.out", "w", stdout);
  32. qread(n);
  33. qread(m);
  34. for (int i = 1; i <= n; ++i)
  35. qread(r[i]);
  36. for (int i = 1; i <= m; ++i){
  37. qread(d[i]);
  38. qread(s[i]);
  39. qread(t[i]);
  40. }
  41. fclose(stdin);
  42. int ll = 1, rr = m;
  43. while (ll <= rr){
  44. int mid = (ll + rr) >> 1;
  45. if (! ok(mid)){
  46. ans = mid;
  47. rr = mid - 1;
  48. }
  49. else
  50. ll = mid + 1;
  51. }
  52. if (! ans)
  53. putchar('0');
  54. else
  55. printf("-1\n%d", ans);
  56. }
  57. inline bool ok(int x){
  58. std::fill(ss, ss + MAX, 0);
  59. sum = 0;
  60. for (int i = 1; i <= x; i++){
  61. ss[s[i]] += d[i];
  62. ss[t[i] + 1] -= d[i];
  63. }
  64. for (int i = 1; i <= n; i++){
  65. sum += ss[i];
  66. if (sum > r[i])
  67. return false;
  68. }
  69. return true;
  70. }