zoukankan      html  css  js  c++  java
  • P1083借教室 noip提高组复赛2012

    读完题目我们大概就可以想到一种暴力解法了

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int N=1e6+5;
    int sum[N],d,r[N],s,t,n,m;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&r[i]);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&d,&s,&t);
            for(int j=s;j<=t;j++)
            {
                sum[j]=sum[j]+d;
            if(r[j]<sum[j])
            {
                cout<<"-1"<<endl<<i;
                return 0;
             }
            }
        }
        cout<<"0";
        return 0;
    }

    要是能在考场上混45分,那还是不错的。

    差分数组


    设一个数组diff【】。

    那么什么是差分数组呢:

    用diff[ i ]记录当前项与上一项的差值:diff[ i ]=a[ i ]-a[ i-1 ];

    所以如果我们知道diff【0...i】,就可以求出a【i】了

    它的厉害之处在于哪里呢?

    如果我们要让a[ l ],a[ l+1 ]...a[ r ]的值同时加上或减去一个数,那么可以这么做

    diff[ l ]+=x;

    diff[ r+1 ]-=x;

    因为对于这个数列,只有两处相邻差发生改变。所以可以O(1)地修改。

    对于这道题

    如果要检查第一份到第 i 份订单是否有需要修改的,

    那么就这么就根据上面说的方法,把d[ 1 ]到d[ i ]一个个加到相应的区间上。

    bool check(int per)
    {
        memset(diff,0,sizeof(diff));
        for(int i=1;i<=per;i++)
        {
            diff[s[i]]+=d[i];
            diff[t[i]+1]-=d[i];
        }
        for(int i=1;i<=n;i++)
        {
            need[i]=need[i-1]+diff[i];
            if(need[i]>r[i]) return true;
        }
        
        return false;
    }

    所以我们就从1到n跑一遍check就可以了对不对?

    别急,先看看能不能二分。

    这道题里,如果第 i 份订单需要修改,后面的订单也无法满足。满足单调性。

    那么就可以二分了,节约大把时间。

    while(l<=r)
        {
            mid=(l+r)>>1;
            if(check(mid))//找到一个可行解,保存下来,看看有没有更优的(更靠前 
            {
                ans=mid;
                r=mid-1;
            }
            else l=mid+1;
        }

    本文结束,谢谢大佬

    顾z 的个人中心 - 洛谷 | 计算机科学教育新生态
    https://www.luogu.org/user/87960

    _皎月半洒花 的个人中心 - 洛谷 | 计算机科学教育新生态
    https://www.luogu.org/user/28313

  • 相关阅读:
    病毒软件测试代码
    如何将WIN安全设置重置回默认值
    今天值班非常不爽。
    FTP命令(2)
    WORD操作
    DELPHI事务
    DELPHI一些常用的技巧
    钩子学习心得
    (转 )Delphi指针如何指向使用with开域语句创建的无名组件对象
    WebBrowser 操作记要 (DELPHI)
  • 原文地址:https://www.cnblogs.com/Neptune0/p/11844345.html
Copyright © 2011-2022 走看看