zoukankan      html  css  js  c++  java
  • “玲珑杯”ACM比赛 Round #13 B -- 我也不是B(二分排序)

    传送门

    题意

    开始有一个空序列s,一个变量c=0,接着从左往右依次将数组a中的数字放入s的尾部,每放一个数字就检测一次混乱度K,当混乱度k大于M时就清空序列并让c=c+1,K = Bi * Vi(1<=i<=k(序列总长度)的总和),Bi表示序列中第i小的数字,Vi是给定的非递减的数,输出每次加入序列后的变量c

    分析

    令当前左端点为L, 我们先找到一个最小的K, 使得[L,L+2K)这个区间混乱度超过M
    然后右端点在[L+2K−1,L+2K)中二分即可
    考虑每删去至少2K−1
    个数, 所需要的时间复杂度最大为O(2KKlogN)
    故总复杂度为O(Nlog2N)

    trick

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define F(i,a,b) for(int i=a;i<=b;++i)
    #define R(i,a,b) for(int i=a;i<b;++i)
    #define mem(a,b) memset(a,b,sizeof(a))
    #pragma comment(linker, "/STACK:102400000,102400000")
    inline void read(int &x){x=0; char ch=getchar();while(ch<'0') ch=getchar();while(ch>='0'){x=x*10+ch-48; ch=getchar();}}
    
    int n;
    ll m;
    int a[300300],v[300300],Pow[25],temp[300300];
    int ans[300300];
    bool judge(int l,int r)
    {
        ll sum=0LL;
        int cnt=0;
        for(int i=l;i<=r;++i) temp[cnt++]=a[i];
        sort(temp,temp+cnt);
        for(int j=0;j<cnt;++j) sum+=(ll)temp[j]*v[j];
        if(sum>m) return 1;return 0;
    }
    int erfen(int l,int left,int right)
    {
        while(left<right)
        {
            int mid=(left+right>>1);
            if(judge(l,mid)) right=mid;else left=mid+1;
        }
        return left;
    }
    int check(int l,int n)
    {
        int left=l,right=l;
        for(int i=0;;++i,right+=Pow[i])
        {
            if(right>n) right=n;
            if(judge(l,right)) break;
            left=right+1;
            if(right==n) break;
        }
        return erfen(l,left,right);
    }
    int main()
    {
        Pow[0]=1;
        F(i,1,24) Pow[i]=Pow[i-1]*2;
        while(scanf("%d %lld",&n,&m)!=EOF)
        {
            F(i,0,n-1) scanf("%d",a+i);
            F(i,0,n-1) scanf("%d",v+i);
            mem(ans,0);
            for(int i=0;i<n;)
            {
                int j=check(i,n);
                ans[j]=ans[i==0?0:i-1]+1;
                i=j+1;
            }
            for(int i=1;i<n;++i) ans[i]=max(ans[i],ans[i-1]);
            for(int i=0;i<n;++i) printf("%d%c",ans[i],i==n-1?'
    ':' ');
        }
        return 0;
    }
    
  • 相关阅读:
    web单机优化
    html标签
    html基础
    jenkins api
    cobbler api
    Cobbler安装配置简单使用
    ubuntu 12.04下搭建web服务器(MySQL+PHP+Apache) 教程
    在ubuntu12.04上安装6款顶级漂亮的BURG主题
    Setting up an OpenGL development environment in ubuntu
    c++ list 容器
  • 原文地址:https://www.cnblogs.com/chendl111/p/6894530.html
Copyright © 2011-2022 走看看