B:
n*m个口罩分成最少的组使得可以这样分配:
n个医院,每个医院m个口罩。
m个医院,每个医院n个口罩。
为了使得数量最少,每组的口罩尽可能要大。
假设n<m
n个医院,每个医院m个口罩,
我们最多可以让 m/n*m组有n个口罩(当前最大值)。
然后问题转化为了:
n个医院每个医院需要m%n个口罩
m%n个医院,每个医院需要n个口罩。
变化为了子问题,dfs下去即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
vector<int>v;
void gao(int n,int m)
{
if(m==0)return ;
for(int i=1;i<=n/m*m;i++)v.pb(m);
//m个医院需要n%m,n%m个医院需要m,转化为子问题
gao(m,n%m);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
v.clear();
if(n<m)swap(n,m);
gao(n,m);
cout<<v.size()<<endl;
for(auto x:v)
cout<<x<<" ";
cout<<endl;
}
return 0;
}
D:
打表
H:
分析性质可知:
n=x*k
n=x*k+1;
n=1;
先考虑n=x*k的情况:
假设k>=2.
ans=n/2+n/3+……+n/k;
用整数分块即可。
n=x*k+1 -> n-1=x*k;
一样处理。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
const int mod=1e9+7;
//n/2+n/3+n/4+……+n/K
ll cal(ll n,ll k)
{
ll ans=0;
for(ll l=2,r;l<=k;l=r+1)
{
r=n/l?min(n/(n/l),k):k;
ans=(ans+n/l*(r-l+1))%mod;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
ll N,k;
cin>>N>>k;
//n=x*k
ll ans=0;
cout<<(cal(N,k)+cal(N-1,k)+N+k-1)%mod<<endl;
return 0;
}