layout: post

title: Codeforces Round 251 (Div. 2)

author: "luowentaoaa"

catalog: true

tags:

mathjax: true

- codeforces

- 模拟


传送门

A.[Devu, the Singer and Churu, the Joker (签到)

题意

主角有N首不同时长的歌曲,每首歌曲之间需要相隔10分钟,并且歌曲必须连续,再主角唱完歌的时候可以表演每次五分钟的其他节目。问最多表演多少场其他节目, 不能完成演唱输出-1

思路

直接先按照题意安排歌曲,然后再在空缺的时间中填充魔术。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e6+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int a[maxn];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n,d;
cin>>n>>d;
for(int i=1;i<=n;i++)cin>>a[i];
if((n-1)*10>=d){
cout<<-1<<endl;return 0;
}
int cnt=0;
int ex=d-(n-1)*10;
int num=0;
for(int i=1;i<=n;i++){
if(i!=1)num+=10,cnt+=2;
num+=a[i];
}
if(num>d){
cout<<-1<<endl;return 0;
}
else{
cnt+=(d-num)/5;
cout<<cnt<<endl;
}
return 0;
}

B.Devu, the Dumb Guy (贪心)

题意

n个课程,每个课程都有ci个章节,完成一章需要X分钟,但是如果完成一个课程后面的课程每章都会减少一分钟(最少不低于1分钟),问少需要几分完成所有课程。

题解

直接排序 然后根据题意模拟贪心。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e6+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int a[maxn];
int cnt[maxn];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n,x;
cin>>n>>x;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+1+n);
ll sum=0;
for(int i=1;i<=n;i++){
sum+=a[i]*max(1LL*(x-i+1LL),1LL);
}
cout<<sum<<endl;
return 0;
}

C.Devu and Partitioning of the Array (大模拟)

题意

给出N个数,让你分成k块,其中p块的和为偶数

思路

只要知道偶数+偶数=偶数,奇数+奇数=偶数 奇数+偶数=奇数的特性就可以做了,

不过情况比较多需要讨论

先把奇数偶数分类,然后如果奇数比较多,就判断奇数多出来的那些可不可以组成偶数(也就是多出来的是不是偶数个)

注意讨论奇数和偶数分别为0的情况。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e6+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
ll a[maxn];
stack<int>odd,even,exeven,exodd;
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n,k,p;
cin>>n>>k>>p;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]&1)odd.push(a[i]);
else even.push(a[i]);
}
int oddnum=odd.size();
int odd_need_num=k-p;
int even_need_num=p;
if(odd_need_num>oddnum){
cout<<"NO"<<endl;return 0;
}
else{
if((oddnum-odd_need_num)%2!=0){
cout<<"NO"<<endl;return 0;
}
else{
int ex=oddnum-odd_need_num;
for(int i=1;p!=0&&i<=ex;i++){
exeven.push(odd.top());
odd.pop();
}
if(!p){
while(!even.empty()){
exodd.push(even.top());
even.pop();
}
}
if(ex/2+even.size()<even_need_num){
cout<<"NO"<<endl;return 0;
}
cout<<"YES"<<endl;
for(int i=1;i<odd_need_num;i++){
cout<<1<<" "<<odd.top()<<endl;
odd.pop();
}
if(!odd.empty()){
cout<<odd.size()+exodd.size()<<" ";
while(!odd.empty()){
cout<<odd.top()<<" ";
odd.pop();
}
while(!exodd.empty()){
cout<<exodd.top()<<" ";
exodd.pop();
}
cout<<endl;
}
for(int i=1;i<p;i++){
if(!even.empty()){
cout<<1<<" "<<even.top()<<endl;
even.pop();
}
else{
cout<<2<<" "<<exeven.top();
exeven.pop();
cout<<" "<<exeven.top()<<endl;
exeven.pop();
}
}
if(even.size()+exeven.size()==0)return 0;
cout<<even.size()+exeven.size()<<" ";
while(!even.empty()||!exeven.empty()){
if(!even.empty()){
cout<<even.top()<<" ";
even.pop();
}
else{
cout<<exeven.top()<<" ";
exeven.pop();
cout<<exeven.top()<<" ";
exeven.pop();
}
}
}
}
return 0;
}

D.Devu and his Brother (三分)

题意

两个数组A,B.想要数组A的最小值不比数组B的最大值小,一次操作可以让某个数字的一个元素增大或者减小1 问达成目的最少需要几次操作。

思路

题目的意思就是找出一个值X使得A中的所有元素都大于等于X,B中的元素小于等于X。

所以答案就是

\[ans=(\sum_{i=1}^{n}x-a[i])+(\sum_{i=1}^{m}b[i]-x)\\a[i]<x,b[i]>x
\]

假设这个x是最优的解,那么X增大或者减小都会使得ans变大,所以题目就是一个凹函数求最小值了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e6+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
ll a[maxn];
ll b[maxn];
int n,m;
ll check(ll x){
ll ans=0;
for(int i=1;i<=n;i++)if(a[i]<x)ans+=x-a[i];
for(int i=1;i<=m;i++)if(b[i]>x)ans+=b[i]-x;
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>m;
for(int i = 1; i <= n; i++){
cin>>a[i];
}
for(int i = 1; i <= m; i++){
cin>>b[i];
}
ll l=0,r=1e11,ans=inf;
for(int i=1;i<=100;i++){
ll m1=(l+r)/2;
ll m2=(m1+r)/2;
ll ans1=check(m1),ans2=check(m2);
if(ans1>ans2){
l=m1;
ans=min(ans,ans2);
}
else{
r=m2;
ans=min(ans,ans1);
}
}
cout<<ans<<endl;
return 0;
}

E.Devu and Birthday Celebration (莫比乌斯反演,素因子分解,计数原理,组合数学)

题意

Q次询问 给出一个数N 让你分成F份,使得这F份的和为N并且这F份数 最大公约数为1,问有多少种分法。Q,N,F范围都是1-1e5。

思路

如果不考虑公约数 那么答案就是Cn-1,f-1。

设F(n,k)为n个数分成F份并且最大公约数为1的答案数

所以

\[F(n,k)=C_{n-1}^{k-1}-\sum_{g>1}^{n}F(n/g,k)
\]

然后直接递归写就行。

\[F(n)=n分解为k份最大公约数为任意的值
\]

\[G(n)=n分解为k份且最大公约数为n的值
\]

可知

\[F(n,k)=C_{n-1}^{k-1}
\]

同时

\[F(n)=\sum_{d|n}G(d)
\]

于是根据莫比乌斯反演因数反演

\[G(n)=\sum_{d|n}u(d)F(n/d)
\]

/*
莫比乌斯反演
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e6+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
ll inv[maxn],p[maxn];
ll ksm(ll x,ll n){
ll ans=1;
while(n){
if(n&1)ans=(ans*x)%mod;
x=(x*x)%mod;
n>>=1;
}
return ans;
}
int prime[maxn];
bool notprime[maxn];
int mu[maxn];
void init(int n){
mu[1]=1;
int tot=0;
for(int i=2;i<=n;i++){
if(!notprime[i])prime[++tot]=i,mu[i]=-1;
for(int j=1;j<=tot;j++){
if(i*prime[j]>n)break;
notprime[i*prime[j]]=true;
if(i%prime[j]==0){
mu[i*prime[j]]=0;
break;
}
else mu[i*prime[j]]=-mu[i];
}
}
inv[0]=p[0]=1;
for(int i=1;i<=n;i++)
p[i]=p[i-1]*i%mod,inv[i]=ksm(p[i],mod-2);
}
ll cal(int n,int m){
if(n<m)return 0LL;
return p[n]*inv[n-m]%mod*inv[m]%mod;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
init(1e5);
int q;
cin>>q;
while(q--){
ll n,f;
cin>>n>>f;
ll ans=0;
for(int i=1;i*i<=n;i++){
if(n%i==0){
ans=(ans+mu[i]*cal(n/i-1,f-1)+mod)%mod;
if(n/i!=i)ans=(ans+mu[n/i]*cal(i-1,f-1)+mod)%mod;
}
}
cout<<ans<<endl;
}
return 0;
}
/*
枚举GCD值
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e6+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
ll inv[maxn],p[maxn];
ll ksm(ll x,ll n){
ll ans=1;
while(n){
if(n&1)ans=(ans*x)%mod;
x=(x*x)%mod;
n>>=1;
}
return ans;
}
vector<int>G[maxn];
void init(int n){
inv[0]=p[0]=1;
for(int i=1;i<=n;i++)
p[i]=p[i-1]*i%mod,inv[i]=ksm(p[i],mod-2);
for(int i=2;i<=n;i++){
for(int j=i;j<=n;j+=i){
G[j].push_back(i);
}
}
}
ll cal(int n,int m){
if(n<m)return 0LL;
return p[n]*inv[n-m]%mod*inv[m]%mod;
}
ll vis[maxn];
int who[maxn];
ll F(int n,int k,int q){
if(who[n]==q)return vis[n];
ll ans=cal(n-1,k-1);
for(int i=0;i<G[n].size();i++){
ans=(ans-F(n/G[n][i],k,q)+mod)%mod;
}
who[n]=q;
vis[n]=ans;
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
init(1e5);
int q;
cin>>q;
while(q){
ll n,f;
cin>>n>>f;
cout<<F(n,f,q)<<endl;
q--;
}
return 0;
}
/*
枚举GCD倍数
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e6+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
ll inv[maxn],p[maxn];
ll ksm(ll x,ll n){
ll ans=1;
while(n){
if(n&1)ans=(ans*x)%mod;
x=(x*x)%mod;
n>>=1;
}
return ans;
}
void init(int n){
inv[0]=p[0]=1;
for(int i=1;i<=n;i++)
p[i]=p[i-1]*i%mod,inv[i]=ksm(p[i],mod-2);
}
ll cal(int n,int m){
if(n<m)return 0LL;
return p[n]*inv[n-m]%mod*inv[m]%mod;
}
vector<int> get(int n){
vector<int>G;
for(int i=2;i*i<=n;i++){
if(n%i==0){
G.push_back(i);
while(n%i==0)n/=i;
}
}
if(n!=1)G.push_back(n);
return G;
}
ll F(int n,int k){
vector<int>G=get(n);
ll ans=0,num=1<<G.size();
for(int i=0;i<num;i++){
ll tmp=1,sign=1;
for(int j=0;j<G.size();j++){
if(i&(1<<j)){
sign*=-1;
tmp*=G[j];
}
}
ans=(ans+sign*cal(n/tmp-1,k-1)%mod+mod)%mod;
}
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
init(1e5);
int q;
cin>>q;
while(q--){
ll n,f;
cin>>n>>f;
cout<<F(n,f)<<endl;
}
return 0;
}

最新文章

  1. Bootstrap栅格系统详解,响应式布局
  2. C# 中的Singleton模式
  3. c#部分---结构体再利用;
  4. ruby中实例变量、类变量等等的区别和联系
  5. Codeforces 712C Memory and De-Evolution
  6. js中substring和substr的用法 (转)
  7. 全国计算机等级考试二级教程-C语言程序设计_第8章_地址和指针
  8. mac os 安装 wget
  9. Exp4恶意代码分析 20164312 马孝涛
  10. studio-3t 配置文件位置
  11. 苹果企业账号打包发布App的详细流程
  12. (转)Java调用Weservice
  13. C# 用户选择单个压缩-系统自带压缩
  14. phaser相关
  15. 如何判断Map中的key或value类型
  16. No.1 selenium学习之路之浏览器操作
  17. sql表值参数
  18. (转)Behavior Tree实践
  19. LOJ2424 NOIP2015 子串 【DP】*
  20. wordpress缓存插件使用提高网站速度

热门文章

  1. AGC016C +/- Rectangle(构造)
  2. Generator实质
  3. WebServer参数长度超出解决
  4. 【题解】SDOI2016征途
  5. redux-saga基本用法
  6. requestAnimationFrame实现一帧的函数节流
  7. HDU1054 Strategic Game(最小点覆盖)
  8. hdu 3473 (划分树)2
  9. matlab求最大公约数和最小公倍数
  10. java JDK动态代理的机制