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

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();
}

相关文章:

  • 【DeepSeek-R1】 API申请(火山方舟联网版)
  • Mongodb数据管理
  • 数据结构与算法面试专题——堆排序
  • 蓝桥练习生
  • HTML【详解】input 标签
  • Linux系统中常见的词GNU是什么意思?
  • 虚拟机安装k8s集群
  • 【C语言】程序环境与预处理
  • 浅聊Docker使用、部署
  • 企业SSL 证书管理指南
  • 微服务SpringCloudAlibaba组件Spring Cloud Gateway网关教程【详解gatway网关以及各种过滤器配置使用,附有示例+代码】
  • 计算机视觉-局部特征
  • ?.、??、||分别是什么,又有哪些区别???
  • kafka为什么这么快?
  • Java和SQL测试、性能监控中常用工具
  • ZOJ 1011 NTA
  • 【第6章:强化学习基础与深度强化学习—6.4 强化学习在游戏、自动驾驶等领域的应用案例】
  • 网络工程师 (40)常见接入网技术
  • windows10+CPU基于openVINO高速部署yolov5
  • CUDA-内存访问模式
  • 我使馆就中国公民和企业遭不公正待遇向菲方持续提出严正交涉
  • 2025年“新时代网络文明公益广告”征集展示活动在沪启动
  • 既是工具又是食物,可食用机器人开启舌尖上的新科技
  • 上交所五方面落实募资新规:强化关键少数责任和股东权利保障
  • 车建兴被留置:跌落的前常州首富和红星系重整迷路
  • 江西3人拟提名为县(市、区)长候选人