A. Drinks Choosing

有 $n$ 个人,每个人各有一种最喜欢的饮料,但是买饮料的时候只能同一种的两个两个买(两个一对)

学校只打算卖 $\left \lceil \frac{n}{2} \right \rceil$ 对

这意味着有些学生喝不到最喜欢的饮料,求最多有多少学生能喝的最喜欢的饮料

人数和饮料种数均小于等于 $1000$

直接贪心,对于喜欢同一种饮料的学生中,如果人数为奇数,要么单独买一对,然后把另一个给不喜欢这种饮料的人

要么喝自己不喜欢的饮料,设喜欢某种饮料的学生人数为奇数的饮料种数为 $x$,那么显然答案就是 $\left \lfloor \frac{x}{2} \right \rfloor$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ldb;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=1e5+;
int n,k,a[N],cnt[N],ans;
int main()
{
n=read(),k=read();
for(int i=;i<=n;i++) a[i]=read(),cnt[a[i]]++;
for(int i=;i<=k;i++)
if(cnt[i]&) ans++;
printf("%d\n",n-ans/);
}

A. Drinks Choosing

B. Sport Mafia

有个人,进行了 $n$ 此操作,每次操作分为两种,放一些糖到盒子里,并且放的数量比上一次多 $1$,或者如果盒子有糖也可以选择从盒子里拿一个糖吃掉

第一次操作固定是往盒子里放一个糖,已知操作次数 $n$ 和最后剩下的糖的数量 $k$

求 $ta$ 吃的糖数量,保证有解

直接设进行了 $x$ 次 $1$ 操作,那么剩下的操作都是吃糖,所以可以列出方程

$x(x+1)/2=k+(n-x)$

解一下方程答案的公式就出来了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ldb;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
ll n,k;
int main()
{
n=read(),k=read();
// p*(p+1)/2=k+n-p
// p^2+p=2k+2n-2p
// p^2+3p-(2k+2n)=0
// 9+8(n+k)
// (-3+sqrt(8(n+k)+9))/2
ll p=(sqrt((n+k)*+)-)/;
printf("%lld\n",p*(p+)/-k);
return ;
}

B. Sport Mafia

C. Basketball Exercise

两排长度为 $n$ 的数 $A,B$,从左到右每次可以选择 $A,B$ 中的一个或者不选,对于同一排不能选择相邻的数,求能得到的最大值

显然设 $F[i][0/1]$ 表示从左到右选到第 $i$ 个位置,当前位置选择的数是 $A/B$,转移显然,具体看代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ldb;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=1e6+;
int n,a[N][];
ll f[N][];
int main()
{
n=read();
for(int i=;i<=n;i++) a[i][]=read();
for(int i=;i<=n;i++) a[i][]=read();
f[][]=a[][]; f[][]=a[][];
for(int i=;i<=n;i++)
{
f[i][]=max(f[i-][]+a[i][],f[i-][]);
f[i][]=max(f[i-][]+a[i][],f[i-][]);
}
printf("%lld\n",max(f[n][],f[n][]));
return ;
}
 
 
 
 

C. Basketball Exercise

D1. Submarine in the Rybinsk Sea (easy edition)

对于两个数 $A,B$,它们从左到右每一位分别是 $A[1]A[2]...A[m],B[1]B[2]B[m]$

定义函数 $F(A,B)$ 表示把两个数错位插在一起的结果,即 $A[1]B[1]...A[m-1]B[m-1]A[m]B[m]$

(具体例子看原题面)

给定数列 $a[]$,求 $\sum_i\sum_jF(a[i],a[j])$,保证数列中每个数的长度相等

考虑每一个数对答案的贡献,发现当它(设为 $C$)被 $i$ 枚举到时的贡献总是 $C[1]0C[2]0C[3]0...C[m]0$,被 $j$ 枚举到时的贡献总是 $C[1]0C[2]...0C[m]$

显然被 $i,j$ 枚举到的次数都为 $n$,所以贡献可以一起算

具体操作起来写个函数把数转化一下就行了,我的写法要注意 $unsigned\ long\ long$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef unsigned long long ll;
typedef long double ldb;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=1e6+,mo=;
ll n,a[N],f[],ans;
int p[];
ll F(ll x,int type)//把数转换成插入一堆0的结果
{
int len=; for(ll t=x;t;t/=) p[++len]=t%;
ll res=; for(int i=;i<=len;i++) res+=p[i]*f[i*+type];
return res%mo;
}
int main()
{
n=read();
for(int i=;i<=n;i++) a[i]=read();
f[]=; for(int i=;i<=;i++) f[i]=f[i-]*;
for(int i=;i<=n;i++)
ans=(ans+F(a[i],))%mo,ans=(ans+F(a[i],-))%mo;
printf("%lld\n",ans*n%mo);
return ;
}

D1. Submarine in the Rybinsk Sea (easy edition)

D2. Submarine in the Rybinsk Sea (hard edition)

题目同上,唯一的区别就是数列 $a[]$ 中每个数的长度不一定相等

同样考虑每个数的贡献,发现一个数 $C$ 被 $i$ 枚举到时的贡献只和此时被 $j$ 枚举到的数的长度有关,被 $j$ 枚举到时的贡献也同理

所以记录一下长度为 $k$ 的数有多少个,把相同的贡献一起计算就好了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef unsigned long long ll;
typedef long double ldb;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=1e6+,mo=;
ll n,a[N],f[],ans;
int p[],cnt[];
int Len(ll x) { int res=; while(x) res++,x/=; return res; }
ll F(ll x,int type,int num)
{
int len=; for(ll t=x;t;t/=) p[++len]=t%;
ll res=;
for(int i=;i<=min(len,num);i++) res+=p[i]*f[i*+type];
for(int i=num+;i<=len;i++) res+=p[i]*f[num+i];
// cout<<x<<" "<<num<<" "<<res<<endl;
return res%mo;
}
int main()
{
n=read();
for(int i=;i<=n;i++) a[i]=read();
f[]=; for(int i=;i<=;i++) f[i]=f[i-]*;
for(int i=;i<=n;i++) cnt[Len(a[i])]++;
for(int i=;i<=n;i++)
{
// cout<<a[i]<<endl;
// for(int j=1;j<=10;j++) F(a[i],0,j);
// for(int j=1;j<=10;j++) F(a[i],-1,j);
for(int j=;j<=;j++) ans=(ans+F(a[i],,j)*cnt[j]%mo)%mo;
for(int j=;j<=;j++) ans=(ans+F(a[i],-,j)*cnt[j]%mo)%mo;
}
printf("%lld\n",ans);
return ;
}

D2. Submarine in the Rybinsk Sea (hard edition)

E. OpenStreetMap

给一个 $n*m$ 的矩阵,求其中所有 $a*b$ 的子矩阵的元素最小值之和

$n,m<=1000$

和这一题同样的思路:[HAOI2007]理想的正方形

直接单调队列横着竖着扫一遍就好了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef unsigned long long ll;
typedef long double ldb;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=;
int n,m,a,b,h[N][N];
int F[N][N],G[N][N],Q[N];
ll g[N*N],x,y,z,ans;
int main()
{
n=read(),m=read(),a=read(),b=read();
int tot=;
g[]=read(),x=read(),y=read(),z=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
h[i][j]=g[tot];
tot++; g[tot]=(g[tot-]*x+y)%z;
}
for(int i=;i<=n;i++)
{
int L=,R=;
for(int j=;j<=m;j++)
{
while(L<=R&&Q[L]<=j-b ) L++;
while(L<=R&&h[i][j]<=h[i][Q[R]]) R--;
Q[++R]=j; F[i][j]=h[i][Q[L]];
// cout<<F[i][j]<<" ";
}
}
for(int j=;j<=m;j++)
{
int L=,R=;
for(int i=;i<=n;i++)
{
while(L<=R&&Q[L]<=i-a) L++;
while(L<=R&&F[i][j]<=F[Q[R]][j]) R--;
Q[++R]=i; G[i][j]=F[Q[L]][j];
// cout<<G[i][j]<<" ";
if(i>=a&&j>=b) ans+=G[i][j];
}
}
printf("%lld\n",ans);
return ;
}

E - OpenStreetMap

Codeforces Round #574 (Div. 2) A~E Solution的更多相关文章

  1. Codeforces Round #574 (Div. 2)——C. Basketball Exercise(简单DP)

    题目传送门 题意: 输入n,给出两组均为 n个数字的数组a和b,轮流从a和b数组中取出一个数字,要求严格按照当前所选数字的数组下标比上一个所选数字的数组下标更大,计算能够取出的数字加起来的总和最大能为 ...

  2. Codeforces Round #574 (Div. 2)题解

    比赛链接 传送门 A题 题意 \(n\)个人每个人都有自己喜欢喝的\(vechorka\)口味,现在给你\(\lceil n/2\rceil\)箱\(vechorka\),每箱有两瓶,问最多能有多少个 ...

  3. Codeforces Round #574 (Div. 2)

    目录 Contest Info Solutions A. Drinks Choosing B. Sport Mafia C. Basketball Exercise D1. Submarine in ...

  4. Codeforces Round #574 (Div. 2)补题

    A. Drinks Choosing 统计每种酒有多少人偏爱他们. ki 为每种酒的偏爱人数. 输出ans = (n + 1)/2 >  Σki / 2 ? (n + 1)/2 - Σki / ...

  5. Codeforces Round #574 (Div. 2) E.OpenStreetMap

    题目链接 题目的意思就是给你一个矩阵你要求给定子矩阵的最小值的和 单调队列扫两边即可 #include <bits/stdc++.h> #define ll long long #defi ...

  6. Codeforces Round #574 (Div. 2) E. OpenStreetMap 【单调队列】

    一.题目 OpenStreetMap 二.分析 对于二维空间找区间最小值,那么一维的很多好用的都无法用了,这里可以用单调队列进行查找. 先固定一个坐标,然后进行一维的单调队列操作,维护一个区间长度为$ ...

  7. Codeforces Round #574 (Div. 2) D2. Submarine in the Rybinsk Sea (hard edition) 【计算贡献】

    一.题目 D2. Submarine in the Rybinsk Sea (hard edition) 二.分析 相比于简单版本,它的复杂地方在于对于不同长度,可能对每个点的贡献可能是有差异的. 但 ...

  8. Codeforces Round #574 (Div. 2) D1. Submarine in the Rybinsk Sea (easy edition) 【计算贡献】

    一.题目 D1. Submarine in the Rybinsk Sea (easy edition) 二.分析 简单版本的话,因为给定的a的长度都是定的,那么我们就无需去考虑其他的,只用计算ai的 ...

  9. Codeforces Round #371 (Div. 1)

    A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...

随机推荐

  1. device eth0/1 does not seem to be present, delaying initialization

    vmlite虚拟机启动出错,就把这个虚拟机删除掉重新建立,系统虚拟硬盘使用之前的,启动系统后不能上网,通过ifconfig查看网卡没启动,遂启动网卡服务,但是出错,就是:device eth0 doe ...

  2. 【转】C/C++产生随机数

    转自:https://www.cnblogs.com/vectors07/p/8185215.html C/C++怎样产生随机数:这里要用到的是rand()函数, srand()函数,C语言/C++里 ...

  3. sys模块 json pickle模块

    # sys模块# import sys# sys.path# sys.argv# sys.exit() # 脚本退出# print('[%s]'%('#'*1))# print('[%s]'%('#' ...

  4. sklearn.metrics.mean_absolute_error

    注意多维数组 MAE 的计算方法 * >>> from sklearn.metrics import mean_absolute_error >>> y_true ...

  5. Django2 + python3 上传图片

    . ├── db.sqlite3 ├── manage.py ├── myImg │   ├── __init__.py │   ├── __pycache__ │   │   ├── __init_ ...

  6. POJ 1502 MPI MaeIstrom ( 裸最短路 || atoi系统函数 )

    题意 : 给出 N 个点,各个点之间的路径长度用给出的下三角矩阵表示,上上角矩阵和下三角矩阵是一样的,主对角线的元素都是 0 代表自己到达自己不用花费,现在问你从 1 到 N 的最短路,矩阵的 x 代 ...

  7. [CF959B]Mahmoud and Ehab and the message题解

    超级大模拟 直接用map吧string对应到编号上来,然后在开个数组把每个编号对应到每个可以互相转化区块上来,预处理出区块的最小值,使用时直接取最小是即可 代码 #include <cstdio ...

  8. C# WinForm 中Label自动换行 解决方法

    在TableLayoutPannel中放着一些Label如果把Label的AutoSize属性设成True的话,文字超过label长度时就会自动增加,直到后面的字出窗体以外设置成False时,一旦到达 ...

  9. Type Interceptors

    Type Interceptors Castle.Core, part of the Castle Project, provides a method interception framework ...

  10. win10半夜自动开机的问题分析

    win10半夜自动开机的系统日志: 解决方法一: 1.根据日志判断自动唤醒后,windows更新了时间和代理 服务管理器中,关闭windows update, 但是半夜还会自动开 再关闭服务管理器的w ...