专栏文章
题解:P2429 制杖题
P2429题解参与者 2已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @minz37oz
- 此快照首次捕获于
- 2025/12/02 10:42 3 个月前
- 此快照最后确认于
- 2025/12/02 10:42 3 个月前
主要思路
首先 ,暴力枚举大概率会超时。注意到 数据范围较小,,很自然地想到暴力地用容斥原理筛,即
状压枚举 的每个非空子集求和即可。复杂度 。
CPP#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=376544743;
ll n,m,p[39],pro,ans,f;
int main(){
cin>>n>>m; for(int i=1;i<=n;i++) cin>>p[i];
for(int i=1;i<(1<<n);i++){
f=-1; pro=1;
for(int j=1;j<=n;j++){
if(i&(1<<(j-1))){
f*=-1; pro*=p[j]; if(pro>m) break;
}
}
ans+=f*(m/pro*(m/pro+1)/2%mod*pro%mod)%mod; ans%=mod;
}
cout<<ans<<endl;
return 0;
}
提交发现 TLE #1,2,3,疑似是因为 #1,2,3 (
考虑优化。注意到 较大时 很大(具体地,有 时 ),故可将状压枚举改为 DFS 枚举,若当前枚举的质数乘积已经超过 则剪枝,即可通过此题。
AC代码
CPP#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=376544743;
ll n,m,p[39],ans;
void dfs(ll num,ll f,ll pro){
if(num==n+1){
if(pro==1) return;
ans+=f*(m/pro*(m/pro+1)/2%mod*pro%mod)%mod; ans%=mod; return;
}
dfs(num+1,f,pro);
if(pro*p[num]<=m) dfs(num+1,-f,pro*p[num]);
}
int main(){
cin>>n>>m; for(int i=1;i<=n;i++) cin>>p[i];
dfs(1,-1,1); cout<<ans<<endl;
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...