AcWing能被整除的数
思路:
(1)容斥原理的直接应用。首先将所有能被其中任意一个p[i]整除的数的个数加上,再减去所有能被其中任意两个p[i]整除的数的个数,再加上所有能被其中任意三个p[i]整除的数的个数,一次类推......
(2)借助二进制代表是否需要满足次条件,此二进制为1代表需要满足,为0则不需要满足
(3)根据奇偶性判断此数为加还是减(奇为加,偶为减)
code:
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int maxn=20;
int n,m,p[maxn],ans;
int main(){
// freopen("123.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=0;i>j&1){
cnt++;
if((ll)sum*p[j]>n){
sum=-1;
break;
}
sum*=p[j];
}
}
if(sum!=-1){
if(cnt%2){
ans+=n/sum;
}
else ans-=n/sum;
}
}
printf("%d\n",ans);
return 0;
}
214. Devu和鲜花 - AcWing题库
思路:
(1)首先考虑理想状态下,在每一组里面都可以去无限多花,用隔板法考虑,初始(即在每组里面取的花的数量,),令,则所以方案数为:在M+N−1空隙中插入N−1个板,使其分成N组,即
(2)其次在题目要求的情况下,需满足,
正难则反,答案为: 即 ... ....
(3)其中Si即为满足第i个条件的方案数:在第i组内至少取出 Ai+1 朵花,那么此时还剩 M -(Ai+1)朵花,方案数为 【代表的是 】
(4)以此类推,
code:
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int N=30,mod=1e9+7;
ll n,m,down=1;
ll A[N];
int qwi(int a,int k){
int res=1;
while(k){
if(k&1) res=(ll)res*a%mod;
a=(ll)a*a%mod;
k>>=1;
}
return res%mod;
}
int C(ll a,ll b){
if(aa-b;i--) up=i%mod*up%mod;
return (ll)up*down%mod;
}
int main(){
// freopen("123.in","r",stdin);
scanf("%lld%lld",&n,&m);
for(int i=0;i>j&1){
sign*=-1;
a-=A[j]+1;
}
}
ans=(ans+C(a,b)*sign)%mod;
}
printf("%d\n",(ans+mod)%mod);
return 0;
}
215. 破译密码 - AcWing题库
思路:
(1)首先了解莫比乌斯函数,详情见莫比乌斯函数_Galaxy_Su的博客-CSDN博客
(2)了解整除分块
(3)优秀题解:AcWing 215. 破译密码题解 - AcWing
code:
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int N=5e4+20;
int primes[N],cnt;
bool vis[N];
int mobius[N],sum[N];
void Mobius(int n){
mobius[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
primes[cnt++]=i;
mobius[i]=-1;
}
for(int j=0;primes[j]*i<=n;j++){
int t=primes[j]*i;
vis[t]= true;
if(i%primes[j]==0){
mobius[t]=0;
break;
}
mobius[t]=mobius[i]*-1;
}
}
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+mobius[i];
}
}
int main(){
// freopen("123.in","r",stdin);
Mobius(N-1);
int t;
scanf("%d",&t);
while(t--){
int a,b,d;
scanf("%d%d%d",&a,&b,&d);
a/=d,b/=d;
int n=min(a,b);
ll ans=0;
for(int l=1,r;l<=n;l=r+1){
r=min(n,min(a/(a/l),b/(b/l)));
ans+=(sum[r]-sum[l-1])*(ll)(a/l)*(b/l);
}
printf("%lld\n",ans);
}
return 0;
}
(会持续更新)