Codeforces Round 251 (Div. 2)
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。
所以答案就是
\]
假设这个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的答案数
所以
\]
然后直接递归写就行。
\]
\]
可知
\]
同时
\]
于是根据莫比乌斯反演因数反演
\]
/*
莫比乌斯反演
*/
#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;
}
Codeforces Round 251 (Div. 2)的更多相关文章
- Codeforces Round#251(Div 2)D Devu and his Brother
--你以为你以为的.就是你以为的? --有时候还真是 题目链接:http://codeforces.com/contest/439/problem/D 题意大概就是要求第一个数组的最小值要不小于第二个 ...
- Codeforces Round #251 (Div. 2) C. Devu and Partitioning of the Array
注意p的边界情况,p为0,或者 p为k 奇数+偶数 = 奇数 奇数+奇数 = 偶数 #include <iostream> #include <vector> #include ...
- Codeforces Round #251 (Div. 2) B. Devu, the Dumb Guy
注意数据范围即可 #include <iostream> #include <vector> #include <algorithm> using namespac ...
- Codeforces Round #251 (Div. 2) A - Devu, the Singer and Churu, the Joker
水题 #include <iostream> #include <vector> #include <algorithm> using namespace std; ...
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
随机推荐
- 理解First Chance和Second Chance避免单步调试
原文链接地址:http://blog.csdn.net/Donjuan/article/details/3859160 在现在C++.Java..Net代码大行其道的时候,很多代码错误(Bug)都是通 ...
- [Leetcode] Remove duplicate from sorted list ii 从已排序的链表中删除重复结点
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numb ...
- [Leetcode] Populating next right pointer in each node ii 填充每个节点的右指针
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- nowcoder 提高组模拟赛 选择题 解题报告
选择题 链接: https://www.nowcoder.com/acm/contest/178/B 来源:牛客网 题目描述 有一道选择题,有 \(a,b,c,d\) 四个选项. 现在有 \(n\) ...
- 洛谷 [SDOI2015]约数个数和 解题报告
[SDOI2015]约数个数和 题目描述 设\(d(x)\)为\(x\)的约数个数,给定\(N,M\),求$ \sum\limits^N_{i=1}\sum\limits^M_{j=1}d(ij)$ ...
- 如何用listview显示服务端数据
https://www.cnblogs.com/caobotao/p/5061627.html
- BZOJ 2457 双端队列(思维
2457: [BeiJing2011]双端队列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 582 Solved: 253[Submit][Sta ...
- tomcat发布web项目的三种方式
tomcat发布web项目的三种方式 方式一: 配置tomcat 安装目录下的conf/server.xml <Host name="loaclhost">标签里面添加 ...
- 状压dp的题目列表 (一)
状压dp的典型的例子就是其中某个数值较小. 但是某个数值较小也不一定是状压dp,需要另外区分的一种题目就是用暴力解决的题目,例如UVA818 紫书215 题目列表: ①校长的烦恼 UVA10817 紫 ...
- java三
1,深复制与浅复制 浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. 深复制:被复制对象 ...