zoukankan      html  css  js  c++  java
  • codeforce-191E-Thwarting Demonstrations(树状数组+二分+离散)

    题意:

    求第K 大连续区间

    分析:

    二分答案,再n * log(n)判断有几个区间的区间和大于mid,然后调整上下界,使这个值不断的接近k。

    判断符合条件的区间总数:线性扫描sum[n](前n项和)  每次判断以i结尾的区间有几个区间和大于等于mid,累加即可

    // File Name: 191-E.cpp
    // Author: Zlbing
    // Created Time: 2013年08月03日 星期六 15时10分13秒
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    const int MAXN=1e5+100;
    int tree[MAXN];
    int n;
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int pos,int val)
    {
        while(pos<=n)
        {
            tree[pos]+=val;
            pos+=lowbit(pos);
        }
    }
    int read(int x)
    {
        int s=0;
        while(x>0)
        {
            s+=tree[x];
            x-=lowbit(x);
        }
        return s;
    }
    LL sum[MAXN];
    LL num[MAXN];
    int N;
    LL M;
    LL solve(LL mid)
    {
        CL(tree,0);
        LL ans=0;
        for(int i=1;i<=N;i++)
        {
            if(sum[i]>=mid)ans++;
            LL t=sum[i]-mid;
            int a=upper_bound(num+1,num+n+1,t)-num-1;
            int b=lower_bound(num+1,num+n+1,sum[i])-num;
            ans+=read(a);
            add(b,1);
        }
        //cout<<"ans="<<ans<<endl;
        return ans;
    }
    int main()
    {
        while(~scanf("%d%lld",&N,&M))
        {
            sum[0]=0;
            LL l,r;
            REP(i,1,N)
            {
                scanf("%lld",&sum[i]);
                sum[i]+=sum[i-1];
                num[i]=sum[i];
            }
            sort(num+1,num+N+1);
            n=unique(num+1,num+N+1)-num-1;
                //cout<<"l="<<l<<"r="<<r<<endl;
            LL best=-1;
            l=-1e18;
            r=1e18;
            while(l<=r)
            {
                LL mid=l+(r-l+1)/2;
                //cout<<"l="<<l<<"r="<<r<<"mid="<<mid<<endl;
                if(solve(mid)>=M)
                {
                    best=mid;
                    l=mid+1;
                }
                else r=mid-1;
            }
            cout<<best<<endl;
        }
        return 0;
    }
  • 相关阅读:
    oo第四次博客
    oo第三次博客
    oo第二次博客
    oo第一次博客
    OO第四次博客
    OO第三次博客总结
    第二次博客总结
    oo第一次博客总结
    oo第四次博客作业
    oo第三次博客作业
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3236503.html
Copyright © 2011-2022 走看看