zoukankan      html  css  js  c++  java
  • Range k-th Maximum Query-2020百度之星复赛

    题意

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6840

    分析:

    最小等价于每个区间找第 (l+1−k) 小,然后使得和最小,和最大基本等价,所以我们考虑最大。最优方案中,假设 (l=8,k=3),那么一定会这么填 (000001110000011100000111...) 从大到小依次给这些位置 (1) 的位置填上数字。证明大概可以考虑如果我们放了前 (a) 大的,使得尽量多第 (k) 大的大于等于这个数的尽量多,那么就等价于放 (a)(1) ,使得不小于 (k)(1) 的区间尽量多。

    代码实现上,按段处理,每段长度为 (l),对于每段中末尾长度为 (k)的部分,分别求出每个数的贡献次数。

    代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    int a[N],n,l,k;
    bool cmp(int x,int y)
    {
        return x>y;
    }
    ll solve()
    {
        ll ans=0;
        int d=n/l;
        int r=n-d*l;
        for(int i=k;i<d*k;i++)
        {
            int p=n-i+1;
            if(i%k==0) ans+=1LL*(l-k+1)*a[p];
            else ans+=a[p];
        }
        ans+=1LL*(min(r+1,l-k+1))*a[n-d*k+1];
        if(r>l-k)
        {
            for(int i=1;i<=r-(l-k);i++)
                ans+=a[n-k*d-i+1];
        }
        return ans;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&l,&k);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            sort(a+1,a+1+n);
            ll ans=solve();
            printf("%lld ",ans);//最大值
            k=l-k+1;//第l-k+1小
            sort(a+1,a+1+n,cmp);//按相反的顺序
            ans=solve();
            printf("%lld
    ",ans);
        }
    }
    
    
  • 相关阅读:
    Python笔记初识
    visio开发者图形分类个人爱好
    亿图图示与visio结合使用
    xmind visio mindmanager edraw比较
    Pycharm安装步骤
    win32com问题
    Win32.com安装
    Pycharm安装步骤
    Phython笔记初识
    跨域问题解决方案
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13468298.html
Copyright © 2011-2022 走看看