ABC440DEF简要题解

ABC440

ABC440D

题意:给定一个长度为 n n n 的包含不同整数的数组, q q q 次询问,每次询问不在数组当中出现过的大于等于 x x x 的第 y y y 个数字。
1 ≤ n , q ≤ 3 e 5 1 \leq n,q \leq 3e5 1≤n,q≤3e5
1 ≤ a i , x , y ≤ 1 e 9 1 \leq a_i,x,y \leq 1e9 1≤ai,x,y≤1e9

令 f ( l , r ) f(l,r) f(l,r) 表示区间内不在数组当中出现过的数字个数,易证明,左端点固定时该函数具有单调性。

所以我们可以二分答案的右端点,找到满足 f ( x , t ) ≥ y f(x,t) \geq y f(x,t)≥y 的第一个 t t t 即可。这个个数也可用二分快速求得。

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,q;
int a[1000005];
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>q;
    for(int i=1;i<=n;i++)cin>>a[i];
    sort(a+1,a+1+n);
    while(q--){
        int x,y;cin>>x>>y;
        int cnt0=lower_bound(a+1,a+1+n,x)-a-1;
        ll l=1,r=2e9+2;
        while(l<=r){
            ll mid=l+r>>1;
            int cnt=mid-x+1-(upper_bound(a+1,a+1+n,mid)-a-1-cnt0);
            if(cnt>=y)r=mid-1;
            else l=mid+1;
        }
        cout<<l<<"\n";
    }
}

ABC440E

前置知识点:P1631序列合并

给定 n n n 个可以无限选择的数字,任意选择形成恰好为 k k k 的可重集,求出前 x x x 大的集合的和。

1 ≤ n ≤ 50 1 \leq n \leq 50 1≤n≤50
1 ≤ k ≤ 10 5 1 \leq k \leq 10^5 1≤k≤105
1 ≤ x ≤ m i n ( 10 5 , C n + k − 1 k ) 1 \leq x \leq min(10^5,C_{n+k-1}^k) 1≤x≤min(105,Cn+k−1k)

初始最大值一定是所有数字都选最大的。

考虑将一个最大值替换成更小值能形成的所有方案,可以保证次大值一定在这些方案中取到。

由于替换顺序可能会产生影响(如先将一个5替换成3再将一个5替换成4,反过来操作形成的可重集是一样的),我们额外增加一个替换条件,新替换的数字一定比上一次替换的数小。

我们用一个堆维护{当前集合的和,剩余可替换最大值,上一轮替换的数字},这样每次从堆顶取出的集合一定是剩下所有集合当中最大值,同时再取出的集合基础上修改一个最大值最多形成 n n n个不同的更小的集合。

总复杂度为 O ( n x l o g ( n x ) ) O(nxlog(nx)) O(nxlog(nx))

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,k,x;
ll a[55];
int main(){
    cin>>n>>k>>x;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+n);
    priority_queue<array<ll,3>>q;
    q.push({a[n]*k,k,n-1});
    for(int i=1;i<=x;i++){
        auto [sum,mx,y]=q.top();
        q.pop();
        cout<<sum<<"\n";
        if(mx){
            for(int j=1;j<=y;j++){
                q.push({sum-a[n]+a[j],mx-1,j});
            }
        }
    }
}

ABC440F

暂未编辑

相关推荐
带土18 小时前
4. C++ static关键字
开发语言·c++
橘颂TA8 小时前
【Linux】死锁四条件的底层逻辑:从锁冲突到 STL 组件的线程安全实践(Ⅵ)
linux·运维·服务器·c++·死锁
C++ 老炮儿的技术栈8 小时前
什么是通信规约
开发语言·数据结构·c++·windows·算法·安全·链表
零小陈上(shouhou6668889)8 小时前
K-近邻算法 - lazy learning的代表
算法·近邻算法
有一个好名字9 小时前
力扣-从字符串中移除星号
java·算法·leetcode
萧瑟其中~9 小时前
二分算法模版——基础二分查找,左边界查找与右边界查找(Leetcode的二分查找、在排序数组中查找元素的第一个位置和最后一个位置)
数据结构·算法·leetcode
码上就好ovo9 小时前
Atcoder Beginnner Contest 440
算法
高洁019 小时前
CLIP 的双编码器架构是如何优化图文关联的?(3)
深度学习·算法·机器学习·transformer·知识图谱