zoukankan      html  css  js  c++  java
  • luogu P1038借教室【Noip提高组2012】

    这道题我读完题目的第一感觉是:

    这不就是个线段树??用线段树维护区间最小值,检查是否满足订单要求即可判断。

    对于修改操作直接在区间上进行。

    据说会卡一卡线段树,但是貌似写一个懒标记,连zkw线段树都不用,然后读优,什么的随便卡卡就可以A了

    后来想了想,就这么显然的直接拿线段树去A题显然没什么意义,于是决定想一波正解

    正解的一般解法都是差分前缀和+二分

    当然主要都是二分。

    然后我绞尽脑汁不知道怎么写,后来发现是不会算复杂度限制了我的想象力。

    二分天数十分显然,在1~m间二分,对于每一个mid,我们假定,订单就一定会在这一天出锅,然后剩下的就是判断这一天会不会出锅。

    对于判断的方式,我们另开一个数组,记录类似订单能够为总的教室数量贡献或是拿走的信息

     我们假设这个数组是room_add,order_l, order_r, order_room分别代表订单从第order_l天开始到第order_r天结束,每天借order_room间教室

    对于每份订单:在room_add[order_l[i]]上加上order_room, 相应的,在room_add[order_r[i]+1]上减去order_room

    分别表示订单在order_l天得到了order_room间教室,而在order_r天失去了order_room间教室,也就是为下一个订单提供了order_room间教室。

    我们很容易想到,对于两份相邻的订单,若是后一份订单得到的教室加上前一份订单失去的教室的数量比a[i](a[i]表示每天能提供的教室数量)还大,说明我们肯定无法满足后一份订单,就出锅了。

    但是我们二分的是在哪一天出锅,所以这个时候我们要把二分范围缩小

    反之扩大

    最后如果二分结束后r等于m,就表示中间一定有出过锅,导致r的范围缩小了

    详细见代码实现

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define uint unsigned int
     4 using namespace std;
     5 const int maxn = 1000086;
     6 struct shiki {
     7     int l, r;
     8     int room;
     9 }order[maxn];
    10 int n, m;
    11 int a[maxn], room_add[maxn];
    12 
    13 inline int read() {
    14     int x = 0, y = 1;
    15     char ch = getchar();
    16     while(!isdigit(ch)) {
    17         if(ch == '-') y = -1;
    18         ch = getchar();
    19     }
    20     while(isdigit(ch)) {
    21         x = (x << 1) + (x << 3) + ch - '0';
    22         ch = getchar();
    23     }
    24     return x * y;
    25 }
    26 
    27 inline bool check(int aim_day) {
    28     memset(room_add, 0, sizeof(room_add));
    29     for(register uint i = 1; i <= aim_day; ++i) {
    30         room_add[order[i].l] += order[i].room;
    31         room_add[order[i].r + 1] -= order[i].room;
    32     }
    33     for(register uint i = 1; i <= n; ++i) {
    34         room_add[i] += room_add[i - 1];
    35         if(room_add[i] > a[i]) return true;
    36     }
    37     return false;
    38 }
    39 
    40 int main() {
    41     n = read(), m = read();
    42     for(int i = 1; i <= n; ++i)
    43          a[i] = read();
    44     for(int i = 1; i <= m; ++i)
    45         order[i].room = read(), order[i].l = read(), order[i].r = read();
    46     int l = 1, r = m;
    47     while(l < r) {
    48         int mid = l + r >> 1;
    49         if(check(mid)) r = mid;
    50         else l = mid + 1;
    51     }
    52     if(r != m) cout << -1 << '
    ' << l << '
    ';
    53     else cout << 0 << '
    ';
    54     return 0;
    55 }
  • 相关阅读:
    Scala In 5 Years – My Prediction « GridGain – Real Time Big Data
    牛魔王珍满福拉面 北京团购网|京东团购
    Build WebKit On Windows 白果果白的专栏 博客频道 CSDN.NET
    fabulous
    Selenimu做爬虫 oscarxie 博客园
    EA gpl
    数据挖掘与Taco Bell编程
    test cpp could not compiled on ubuntu use g++,i'll tried lateor on win platform
    How to use ActiveRecord without Rails
    svn添加新项目管理并添加到trac 知识是一种越吃越饿的粮食 ITeye技术网站
  • 原文地址:https://www.cnblogs.com/ywjblog/p/9515755.html
Copyright © 2011-2022 走看看