zoukankan      html  css  js  c++  java
  • Noip 2012 借教室 (二分答案+差分数组)

    题面

    题目链接

    思路

    朴素的想法我们回去暴力修改区间元素,从而判断教室能否够用,但是看数据范围显然这会超时,既然区间问题我们立马想到前缀和和差分数组,and线段树和树状数组,这里不写树状数组和线段树的做法。我们看数据测试量,然后看了一下,这个答案具有线性性质,所以我们可以二分加速,所以我们二分mid,去找不满足条件的最右点,然后在check里面,我们维护一个差分数组,来保存我们要存的教室的数量,最后累加一次前缀和,发现有元素大于原有教室个数,那么我们就判定这个条件下是行不通的。

    代码实现

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <list>
    #include <map>
    #include <queue>
    #include <stack>
    #include <bitset>
    #include <algorithm>
    #include <numeric>
    #include<vector>
    #include <functional>
    #define x first
    #define y second 
    using namespace std;
    typedef long long ll;
    const int maxn=1000005;
    int r[maxn],s[maxn],e[maxn],d[maxn],l,ri,cf[maxn],need[maxn];
    int n,m;
    bool check (int mid) {
        memset (cf,0,sizeof (cf));
        for (int i=1;i<=mid;i++) {
          cf[s[i]]+=d[i];
          cf[e[i]+1]-=d[i];
        }
        for (int i=1;i<=n;i++) {
            need[i]=need[i-1]+cf[i];
            if (need[i]>r[i]) return 0; 
        }
        return 1;
    }
    int main () {
        cin>>n>>m;
        for (int i=1;i<=n;i++) cin>>r[i];
        for (int i=1;i<=m;i++) {
           cin>>d[i]>>s[i]>>e[i];
        }
        l=1,ri=m;
        if (check(m)) {
         cout<<0<<endl;
         return 0;
        }
        while (l<ri) {
           int mid=(l+ri)/2;
           if (check(mid)) {
               l=mid+1;
           }
           else ri=mid;
        }
        cout<<-1<<endl<<l;
        return 0;
    }
    
    
  • 相关阅读:
    在Ubuntu下编译WebKit源码--qt
    Ubuntu 编译Webkit --gtk
    windows远程桌面访问ubuntu12.04
    CentOS下SVN服务器的搭建使用
    Centos搭建SVN服务器三步曲
    StringRedisTemplate常用操作
    MySQL中DATETIME、DATE和TIMESTAMP类型的区别
    mysql 时间索引执行计划
    MySQL大文本类型
    API网关原理
  • 原文地址:https://www.cnblogs.com/hhlya/p/13193922.html
Copyright © 2011-2022 走看看