zoukankan      html  css  js  c++  java
  • 洛谷1404平均数

    我的妈呀...真的好长时间没有去做题了,开始做啦

    今天的这道题只是一个二分

    但是思维很好(毕竟刘神都不会)

    这道题是在看算法进阶二分的时候看到的题目,用刘神的话讲,套路啦

    思维1:二分出一个答案,并且将所有的值减去该答案,然后得到一个新的序列bi如果满足条件的连续区间,其累加和一定大于或等于零

    思维2:如何O(n)求出该答案是否成立,就是计算出新的序列bi的前缀和si,如果在1到i-m之间存在j使得s[i]-s[j]>=0,则答案一定成立

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    //#include<bits/stdc++.h>
    using namespace std;
    int n,m;
    long long a[100010],b[100010],l=200000000,r=0,mid,c[100010];
    bool work(long long p)
    {
        c[0]=0;
        b[0]=0;
        long long Min=1ll*200000000000;
        for(int i=1;i<=n;i++)
        {
            b[i]=b[i-1]+a[i]-p;
            c[i]=min(c[i-1],b[i]);
        }
        c[0]=0;
        for(int i=n;i>=m;i--)
        {
            if(b[i]-c[i-m]>=0)return true;
        }
        return false;
        /*for(int i=1;i<=n;i++){
            b[i]=b[i-1]+a[i]-p;
            if(i>=m) Min=min(b[i-m],Min);//更新Min
            if(b[i]-Min>=0) return 1;
        }
        return 0;*/
    }
    int main()
    {
        //freopen("xf.in","r",stdin);
        //freopen("xf.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            a[i]*=1000;
            l=min(l,a[i]);
            r=max(r,a[i]);
        }
        while(l+1<r)
        {
            mid=(l+r)>>1;
            if(work(mid))l=mid;
            else r=mid;
        }
        if(work(r))printf("%lld
    ",r);
        else printf("%lld
    ",l);
        return 0;
    }

    不过在开始的时候,我在不同的oj上(poj,luogu,duoxiao)都会出现一个点的WA,最后感谢刘神帮我检查出了bug,原来是我的c[0]其实

    是存在意义的,不能赋值为无穷大,改为0就a掉了

  • 相关阅读:
    matplotlib直方图学习小记
    matplotlib饼状图学习小记
    P2306 被yyh虐的mzc
    P1776 宝物筛选_NOI导刊2010提高(02)&& 多重背包二进制优化
    51NOD 1445 变色DNA
    51NOD 1459 迷宫游戏
    CODEVS 1001 舒适的路线
    P4514 上帝造题的七分钟
    1082 线段树练习 3 && 树状数组区间修改区间查询
    P4145 上帝造题的七分钟2 / 花神游历各国
  • 原文地址:https://www.cnblogs.com/mybing/p/13554879.html
Copyright © 2011-2022 走看看