1 条题解

  • 0
    @ 2025-8-24 23:03:26

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Kenma
    入得此门不回首,无需宣之于口

    搬运于2025-08-24 23:03:26,当前版本为作者最后更新于2024-08-26 21:06:53,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    P11010 解题报告

    前言

    很好猜的结论题。

    这是篇和官解证明思路略有出入的题解。

    思路分析

    结论题当然要手玩数据了

    pp 表示 nn 的最大真因子,即不等于自身的最大因子。特别地,当 nn 为质数时,p=1p=1

    结论:Alice 获胜当且仅当 nk+1>pn-k+1 > p

    考虑怎样证明。

    (注:为方便表述,下述集合 AA 等价于 序列 aa

    充分性

    nk+1>pn-k+1 > p \Rightarrow Alice 获胜。

    考虑构造这样一个集合 A={nk+1,1,1,,1}A = \left \{ n-k+1,1,1,…,1 \right \}

    不难发现,Bob 想要划分的非空集合,其元素之和至大为 pp。当 nk+1>pn-k+1 > p 时,集合 AA 中元素 nk+1n-k+1 无法被划分至任何一个集合。

    必要性

    nk+1pn-k+1 \le p \Rightarrow Alice 失败。

    考虑构造一种合法的划分方式。设 pp 为所划分的集合的元素和。将集合 AA 分为 11 和 非 11 元素。不难发现,Bob 获胜当且仅当非 11 元素之和可被划分为 mm 个集合,且每个集合的元素和不超过  nm\ \lfloor \frac{n}{m} \rfloor

    弱化条件:限定 Bob 所划分的集合元素和为 pp

    p=2p=2 时,Bob 只需要构造一个和恰好为 pp 的集合即可。不妨将集合 AA 中极大元素和与所有 11 划分至同一集合。其中,极大元素和定义为不大于 pp 的最大可能的元素和。

    因为集合 AA 中最大的元素不大于 pp,所以只需要保证极大元素和与所有 11 的和不小于 pp 即可。

    不难发现,极大元素和是一个 01 背包问题,这启发我们打表验证(在 IOI 赛制中,其实可以交一发来验证)。

    打表验证可知,当 p=2p=2 时,在题目限定的数据范围内,结论成立。

    然后改变弱化条件:限定 Bob 所划分的集合元素和为 np\frac{n}{p}

    p=3p = 3 时,构造如下:将非 11 元素升序排序,找到一个位置 pospos,使得 $\sum_{i=1}^{pos} a_i \le \frac{n}{p},a_{pos} \le \frac{n}{p},\sum_{i=pos+1}^{n} a_i \le \frac{n}{p}$。因为 nk+1pn-k+1 \le p,所以 pospos 一定存在。

    p>3p >3 时,将 p=3p=3 中所构造的集合拆分,结果一定不劣。

    代码实现

    我采用了线性筛 O(V)O(V) 预处理 ppO(1)O(1) 回答询问的实现方式,总体复杂度为 O(V+T)O(V+T)。但是可能有点卡空间。

    AC code

    #include<bits/stdc++.h>
    using namespace std;
    int t,n,k;
    bool not_prime[100000005];
    int prime[50000005],maxn[100000005],cnt;
    void seive(int n){
    	for(int i=2;i<=n;i++){
    		if(!not_prime[i]) prime[++cnt]=i,maxn[i]=1;
    		for(int j=1;j<=cnt && i*prime[j]<=n;j++){
    			not_prime[i*prime[j]]=1;
    			maxn[i*prime[j]]=i;
    			if(i%prime[j]==0) break;
    		}
    	}
    }
    int main(){
    	seive(100000000);
    	cin>>t;
    	while(t--){
    		cin>>n>>k;
    		if(n-k+1>maxn[n]) cout<<"Alice"<<'\n';
    		else cout<<"Bob"<<'\n';
    	}
    }
    

    后记

    在考场上,证明结论可以采用证明与打表验证结合的做法,可能会有奇效。

    祝点赞的各位 CSP/NOIPCSP / NOIP rp++rp++

    • 1

    信息

    ID
    9875
    时间
    3000ms
    内存
    512MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者