当前位置: 首页 > article >正文

ABC393E/F简要题解

ABC393E

给定数组 A A A,求包含元素 A i A_i Ai的大小为 k k k的子集中最大的最大公约数。

题解:

首先思考对于整个数组所有包含 k k k个元素的子集中最大的GCD是多少,可以怎么求。

我们发现,如果一个数 x x x,数组中如果存在至少 k k k个数是它的倍数,那么我们一定可以找到一个大小为 k k k的子集,使得 x x x是这个集合的公约数。

因为总的值域比较小,所以我们可以使用一个桶统计所有数字的出现次数,然后使用调和级数枚举的方式求出对于每个数 i i i,数组当中有多少数是它的倍数。

如果一个数 i i i,满足它的倍数个数在数组 A A A中的出现次数大于 k k k,那么对于所有 i i i的倍数,我们一定都能找到一个大小为 k k k的集合使得公约数是 i i i。所以我们可以维护一个ans数组, a n s i ans_i ansi表示如果选择了一个值为 i i i的数,最大的答案是多少。对于所有的 A i A_i Ai,直接输出对应的ans即可。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
int n,k;
int a[2000005];
int cnt[1000005];
int sum[1000005];
int ans[2000005];
void solve(){
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        cnt[a[i]]++;
    }
    for(int i=1;i<=1e6;i++){
        for(int j=i;j<=1e6;j+=i){
            sum[i]+=cnt[j];
        }
    }
    for(int i=1;i<=1e6;i++){
        if(sum[i]>=k)
            for(int j=i;j<=1e6;j+=i){
                ans[j]=max(ans[j],i);
                //ans[j]=i;
            }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[a[i]]<<endl;
    }
}
signed main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    solve();
}

ABC393F

给定数组 A A A, q q q次询问前缀 r i r_i ri中所有小于 x i x_i xi的数组成的最长上升子序列是多少。

考虑二分栈求最长上升子序列做法,栈中元素表示对应LCS为 i i i时最后一个数字的最小值,所以我们可以直接将所有询问离线之后在对应的栈上二分找到答案即可。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define pii pair<int,int>
using namespace std;
int n,q;
int a[200005];
vector<pii>ask[200005];
void solve(){
    cin>>n>>q;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=q;i++){
        int x,y;cin>>x>>y;
        ask[x].push_back({y,i});
    }
    vector<int>st(1,0);
    vector<int>ans(q+1,0);
    for(int i=1;i<=n;i++){
        int l=0,r=st.size()-1;
        while(l<=r){
            int mid=l+r>>1;
            if(st[mid]<a[i])l=mid+1;
            else r=mid-1;
        }
        if(l==st.size())st.push_back(a[i]);
        else st[l]=a[i];
        // cout<<i<<" "<<l<<"??\n";
        for(auto [y,id]:ask[i]){
            l=0,r=st.size()-1;
            while(l<=r){
                int mid=l+r>>1;
                if(st[mid]<=y)l=mid+1;
                else r=mid-1;
            }
            ans[id]=r;
        }
    }
    for(int i=1;i<=q;i++)cout<<ans[i]<<endl;
}
signed main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    solve();
}

http://www.kler.cn/a/548100.html

相关文章:

  • 基于web的留守儿童网站的设计与实现
  • 《当DeepSeek遇上豆包:AI大模型的华山论剑》
  • CAS单点登录(第7版)8.委托和代理
  • 筷子科技和抖去推哪个支持短视频矩阵系统源码搭建,OEM贴牌
  • python-leetcode-阶乘后的零
  • 【ISO 14229-1:2023 UDS诊断(会话控制0x10服务)测试用例CAPL代码全解析⑥】
  • CAS单点登录(第7版)3.安装
  • 蓝桥杯之图
  • DeepSeek 背后的技术:GRPO,基于群组采样的高效大语言模型强化学习训练方法详解
  • 基于斜坡单元的机器学习模型预测滑坡易发性,考虑条件因素的异质性
  • 【设计模式】02-理解常见设计模式-结构型模式
  • 基于opencv的 24色卡IQA评测算法源码-可完全替代Imatest
  • YOLOv5-Seg 完全指南:从训练到后处理
  • RAII(Resource Acquisition Is Initialization)机制
  • Ubuntu 24.04 上安装 Nginx
  • C++经典习题
  • 【Python爬虫(1)】专栏开篇:夯实Python基础
  • 服务器被暴力破解的一次小记录
  • 【Docker】Docker中卷的类型、区别及应用
  • 8、k8s的pv和pvc