题解CF93E【Lostborn】
xuanxuan001 · · 题解
Update
- 2024.8.14 怎么被撤了,本来不想管的,
但一看居然是第一篇题解,就还是管一下吧,更正了一下 dp 转移,之前的转移时直接依据代码中的倒序处理写的。感谢@FreedomKing 和@Xiphi 的提醒。
这题显然是个容斥,但是
然后我学校的教练提示我要 DP,我就想了个最初步的:用
边界就在
没什么好解释的,就是最后一项是由于
但是
这时我联想到了数论分块(就那个
于是我就用一个 map 来进行记忆化,然后因为多一个
于是我又开了个
最后教练告诉我可以只把
之后我试了
代码(因为倒序排序不方便,所以我是直接排序然后倒着处理的):
#include<cstdio>
#include<cmath>
#include<algorithm>
#define MAXN 102
#define MAXM 200002
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
#define fOR(i,a,b) for(int i=a;i<b;i++)
#define rOF(i,a,b) for(int i=a;i>b;i--)
using namespace std;
typedef long long ll;
ll qr(){
ll x=1,s=0;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')x=-1;
for(;ch>='0'&&ch<='9';ch=getchar())s=s*10+ch-'0';
return x*s;
}ll n,k,B,a[MAXN],dp[MAXM][MAXN];
ll dfs(ll n,ll now){
if(n==0)return 0;if(now==1)return n/a[1];
if(n<MAXM&&dp[n][now]!=-1)return dp[n][now];
ll ans=n/a[now]+dfs(n,now-1)-dfs(n/a[now],now-1);
if(n<MAXM)dp[n][now]=ans;return ans;
}
int main(){
fOR(i,0,MAXM)fOR(j,0,MAXN)dp[i][j]=-1;
n=qr();k=qr();
FOR(i,1,k)a[i]=qr();
sort(a+1,a+k+1);
printf("%I64d",n-dfs(n,k));
return 0;
}