Codeforces940掉分记
掉分经过##
难得这次时间比较好,下午17:35开始。
本来还很高兴,心想这回肯定不会犯困,没准排名能再上升一些呢,,可惜事与愿违……
上来a题,光看懂题就花了一些时间。
然后开始写,结果第一遍CE,第二遍WA……
出师不利啊!气急败坏,暂时放弃。
然后看b题。
惊喜地发现这类似的题我做过,大概是个bfs?嗯dp也行?
结果发现\(n \leq 10^9\)...真不妙。
这时来了个有关a题的通知,于是又回去看a题。
终于找到之前代码中的问题了,过了pretest
接着c和d题做的还算顺利,1个小时时都过了pretest
剩一个小时,3道题。
e和f看完都没什么好的想法,e想用区间dp,f想用线段树,但好像都不太行……
我又开始慌了……呜哇哇哇啊呀呀呀……
于是又回去看b题
发现居然有约1700人过了b的pretest,我猜这肯定不是道难题。
可能是个鬼畜的贪心?
嗯,想啊想啊想才终于想出来。
交了一发,TLE...又一发,WA...第三发,过了。
此时离比赛结束还有6分钟……
好了,安心下楼吃晚饭吧。
于是,就这样,比了最颓的一场cf...
终测4道题都过了,但由于太慢了,所以排名哗哗向下掉啊…QwQ
题解##
A. Points on the line###
定义一个集合diameter为该集合中的 最大数-最小数
给定一个n元素的集合与 d,求最少去掉原集合中多少个数后该集合的diameter不超过d
输入的所有数据皆\(\leq100\)
想法###
枚举集合中最后剩下的最大值
用这个最大值-d得到集合中可剩下的最小值
找出要去掉的数最少的即可。
代码###
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 105;
int cnt[N],a[N];
int n,k;
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+1+n);
cnt[0]=0;
for(int i=1;i<=n;i++) cnt[a[i]]++;
for(int i=1;i<=100;i++) cnt[i]+=cnt[i-1];
if(n==1) { printf("0\n"); return 0;}
int ans=n,f;
for(int i=n;i>0;i--){
if(a[i]>k) ans=min(ans,n-cnt[a[i]]+cnt[a[i]-k-1]);
else ans=min(ans,n-cnt[a[i]]);
}
printf("%d\n",ans);
return 0;
}
B. Our Tanya is Crying Out Loud###
给定n,k,A,B
设x一开始等于n
x每减1的代价为A,x每/k(前提为x是k的倍数)的代价为B
求将x变为1所需的最小代价
所有输入数据\(\leq 10^9\)
想法一###
dp[i]表示从n变到i的最小代价
dp[i]=min{dp[i+1]+A,dp[i \(\dots\) k]+B}
但n太大了,时间空间都不行。
想法二###
贪心。
先把x不断减1直到x为k的倍数
我们发现,若要x变成x/k,直接/k的代价比一点点减还大的话,直接减,一直减到1就行了,否则直接/k
循环这个过程
代码###
贪心
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1000000005;
int n,k,A,B;
int main()
{
scanf("%d%d%d%d",&n,&k,&A,&B);
ll ans=0;
int x=n,y;
while(x>1){
if(x%k==0) {
if((ll)B>=((ll)x-x/k)*A) {
ans+=(ll)A*(x-1);
x=1;
}
else {
ans+=B;
x=x/k;
}
}
else {
y=max(((x-1)/k)*k,1);
ans+=((ll)x-y)*A;
x=y;
}
}
printf("%lld\n",ans);
return 0;
}
C. Phone Numbers###
给定n,k及一个长度为n的字符串s
求一个长度为k的字符串t,t由出现在s中的字母组成,且t为满足条件的字典序比s大的第一个字符串。
想法###
贪心。
若k>n,则直接在字符串s后面补上k-n个s中的最小字符即可
否则从后面的位往前考虑,看是否能变为一个更大的字符。若可以,便变成比它大的第一个字符,后面位都变成s中的最小字符。
代码###
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 100005;
char s[N];
int n,k,t;
int cnt[30],num[30];
int ans[N];
int main()
{
char ch;
scanf("%d%d",&n,&k);
scanf("%s",s);
for(int i=0;i<n;i++) cnt[s[i]-'a'+1]=1;
for(int i=1;i<=26;i++) cnt[i]+=cnt[i-1];
t=cnt[26];
for(int i=0;i<n;i++) num[cnt[s[i]-'a'+1]]=s[i]-'a'+1;
if(k<=n){
for(int i=0;i<k;i++) ans[i]=cnt[s[i]-'a'+1];
for(int i=k-1;i>=0;i--){
if(ans[i]+1<=t){
ans[i]++;
break;
}
ans[i]=1;
}
for(int i=0;i<k;i++){
ch=num[ans[i]]-1+'a';
cout<<ch;
}
}
else{
for(int i=0;i<n;i++) ans[i]=cnt[s[i]-'a'+1];
for(int i=n;i<k;i++) ans[i]=1;
for(int i=0;i<k;i++){
ch=num[ans[i]]-1+'a';
cout<<ch;
}
}
return 0;
}
D. Alena And The Heater###
有两个长度为n的数组a[]和b[],其中b[]由01组成
b[1]=b[2]=b[3]=b[4]=0
有l与r
对于所有 5 ≤ i ≤ n
当 a[i], a[i - 1], a[i - 2], a[i - 3], a[i - 4] > r 且 b[i - 1] = b[i - 2] = b[i - 3] = b[i - 4] = 1时 b[i]=0
当 a[i], a[i - 1], a[i - 2], a[i - 3], a[i - 4] < l 且 b[i - 1] = b[i - 2] = b[i - 3] = b[i - 4] = 0时 b[i]=1
否则b[i]=b[i-1]
给定a[]与b[],求一组合法的l,r
想法###
从左到右扫b数组
一开始令 l=-INF,r=INF
若存在“00001”的情况,则 l > max{a[i], a[i - 1], a[i - 2], a[i - 3], a[i - 4] }
若存在“11110”的情况,则 r < min{a[i], a[i - 1], a[i - 2], a[i - 3], a[i - 4] }
不断更新l,r即可
代码###
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 100005;
int a[N];
char b[N];
int n;
int maxn(int x){
int ret=-1000000000;
for(int i=0;i<5;i++)
ret=max(ret,a[x-i]);
return ret;
}
int minn(int x){
return min(a[x],min(a[x-1],min(a[x-2],min(a[x-3],a[x-4]))));
}
int main(
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
scanf("%s",b);
int l=-1000000000,r=1000000000,f=0;
for(int i=0;i<n;i++){
if(f<4) f++;
else{
if(b[i]=='1' && b[i-1]=='0'){
l=max(l,maxn(i)+1);
f=1;
}
else if(b[i]=='0' && b[i-1]=='1'){
r=min(r,minn(i)-1);
f=1;
}
}
}
printf("%d %d\n",l,r);
return 0;
}
E. Cashback###
给定一个n元素的数组a[],给定一个数c
规定对于一个k元素的数组b[],其价值为b[]中所有元素的和 - 其中前\(\lfloor \frac{k}{c} \rfloor\)小的元素的和
将a数组分为若干个连续的子数组,求这些子数组的价值和的最小值
\(n \leq 10^5\)
想法###
贪心。
价值和最小,即去掉的前\(\lfloor \frac{k}{c} \rfloor\)小的元素的和最大
我们可以发现,若有一个长度为2c的子数组,那么考虑这个子数组前2小的两个元素i与j
若i与j同在这个子数组的前一半或后一半,那么将这个子数组分为两个长度为c的子子数组价值和会更小
若它们一个在前一半,一个在后一半,那么可以直接将这个子数组分为前后两部分。
故将a数组划分成的子数组长度为1或c
dp+单调队列优化即可
代码###
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100005;
int a[N];
ll sum[N],f[N];
int que[N],head,tail;
int n,c;
int main()
{
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(int i=1;i<=n;i++){
f[i]=f[i-1]+a[i];
while(head<tail && que[head]<=i-c) head++;
while(head<tail && a[que[tail-1]]>=a[i]) tail--;
que[tail++]=i;
if(i>=c) f[i]=min(f[i],f[i-c]+sum[i]-sum[i-c]-a[que[head]]);
}
printf("%lld\n",f[n]);
return 0;
}
F. Machine Learning###
给定一个数组a[],维护下面两种操作:
1.求一段区间[l,r]的mex
2.将a[p]的值改为x
假设在某区间中每个数出现的次数为cnt[i]
这个区间mex为cnt[]中不存在的最小的正整数
想法###
当时比赛的时候还不知道莫队算法
后来才发现原来这就是个带修改莫队的模板题
代码###
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
const int N = 200005;
int read(){
char ch=getchar();
int x=0;
if(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return x;
}
int block;
inline int bl(int x) { return (x-1)/block+1; }
struct que{
int l,r,tim,id;
bool operator < (const que &b) const{
return bl(l)<bl(b.l) || (bl(l)==bl(b.l) && bl(r)<bl(b.r)) || (bl(l)==bl(b.l) && bl(r)==bl(b.r) && tim<b.tim);
}
}q[N];
struct cg{
int id,fr,to;
}d[N];
int n,m,cnt1,cnt2;
int a[N];
map<int,int> num;
int nn;
int size[N],cnt[N],L,R;
void add(int x){
size[cnt[x]]--;
size[++cnt[x]]++;
}
void del(int x){
size[cnt[x]]--;
size[--cnt[x]]++;
}
void cg_add(cg w){
if(L<=w.id && w.id<=R){
del(w.fr);
add(w.to);
}
a[w.id]=w.to;
}
void cg_del(cg w){
if(L<=w.id && w.id<=R){
del(w.to);
add(w.fr);
}
a[w.id]=w.fr;
}
int ans[N];
inline int query(){
for(int i=1;i<=n;i++)
if(size[i]==0) return i;
}
int main()
{
int opt,x,y;
n=read(); m=read();
for(int i=1;i<=n;i++) {
a[i]=read();
if(!num[a[i]]) num[a[i]]=++nn;
a[i]=num[a[i]];
}
for(int i=1;i<=m;i++){
opt=read(); x=read(); y=read();
if(opt==1) q[++cnt1]=(que){x,y,cnt2,cnt1};
else{
if(!num[y]) num[y]=++nn;
y=num[y];
d[++cnt2]=(cg){x,a[x],y};
a[x]=y;
}
}
block=pow(n,0.666);
sort(q+1,q+1+cnt1);
L=1; R=0;
int t=cnt2;
for(int i=1;i<=cnt1;i++){
while(R<q[i].r) add(a[++R]);
while(L>q[i].l) add(a[--L]);
while(R>q[i].r) del(a[R--]);
while(L<q[i].l) del(a[L++]);
while(t>q[i].tim) cg_del(d[t--]);
while(t<q[i].tim) cg_add(d[++t]);
ans[q[i].id]=query();
}
for(int i=1;i<=cnt1;i++) printf("%d\n",ans[i]);
return 0;
}
终于……
Codeforces940掉分记的更多相关文章
- CF480Div2掉分记
rating 1900+参加只有Div2的比赛也记rating了.还以为yyc报名没打会惨惨,原来不交题好像就不算参加.. 本来太晚了不想打,不过有Sinogi大佬带我还是打一打吧,apio之前练练手 ...
- cf掉分记——Avito Code Challenge 2018
再次作死的打了一次cf的修仙比赛感觉有点迷.. 还好掉的分不多(原本就太低没法掉了QAQ) 把会做的前三道水题记录在这.. A: Antipalindrome emmmm...直接暴力枚举 code: ...
- Codeforces Round#402(Div.1)掉分记+题解
哎,今天第一次打div1 感觉头脑很不清醒... 看到第一题就蒙了,想了好久,怎么乱dp,倒过来插之类的...突然发现不就是一道sb二分吗.....sb二分看了二十分钟........ 然后第二题看了 ...
- Codeforces Round 480 Div 2 光荣掉分记
痛 痛苦 痛苦啊. 越接近黄名想的越多了啊…… 都说了不要在意rating这破玩意了…… 没出E就算了,策略问题. 居然还FST了: FST个D就算了: FST个A算个**啊. 紧张的时候总会写出一些 ...
- CODEFORCES掉RATING记 #1
时间:2017.7.16晚 比赛:Educational Codeforces Round 25 比赛开始前去睡觉了...开始后5min才起来 一进去就点开AB,B先加载好,就先做了B.读完题后发现是 ...
- CSP-J&S 2020挂分记
应该是退役记 OI 是一门玄学--考后有感 Day -inf 找各科老师请假备考,看着我倒一倒二的好成绩分纷劝我放弃竞赛,成功请到了假. Day -1 怎么莫名其妙大家都在学些奇怪的东西? 跟风写了一 ...
- CSP-S2021 挂分记
赛前 数了数,这是我第五次来南航,不知道以后还有机会了(2018 NOIP, 2019CSP, 2020CSP, 2020NOIP). 上午一觉睡到 10 点,学了一下感觉很有用的 BIT 倍增,顺手 ...
- CODEFORCES掉RATING记 #5
比赛:Codeforces Round #429 (Div. 2) 时间:2017.8.1晚 这次感觉状态不好,就去打div2了 A:有\(26\)种颜色的气球,每种的数量不一样,你要把这 ...
- CODEFORCES掉RATING记 #4
比赛:Codeforces Round #427 (Div. 2) 时间:2017.7.31晚 开场发现有6道题,都是水题(可能我只会做水题) A:比较\(2t_1+sv_1\)与\(2t_2+sv_ ...
随机推荐
- ZR并查集专题
ZR并查集专题 并查集,作为一个基础算法,对于初学者来说,下面的代码是维护连通性的利器 return fa[x] == x ? x : fa[x] = getf(fa[x]); 所以,但是这对并查集的 ...
- 为什么Redis是单线程,性能还如此高?
一. Redis为什么是单线程 注意:redis 单线程指的是网络请求模块使用了一个线程,即一个线程处理所有网络请求,其他模块仍用了多个线程. 因为CPU不是Redis的瓶颈.Redis的瓶颈最有可能 ...
- CSS3侧栏滑出简单实现
使用css3 的 animation 属性实现的点击滑出侧栏 <!DOCTYPE html> <html lang="en"> <head> & ...
- Java 学习笔记(10)——容器
之前学习了java中从语法到常用类的部分.在编程中有这样一类需求,就是要保存批量的相同数据类型.针对这种需求一般都是使用容器来存储.之前说过Java中的数组,但是数组不能改变长度.Java中提供了另一 ...
- redis分布式锁使用方法
引用: StackExchange.Redis.dll Redlock.CSharp.dll RedLock.dll 代码: public class RedlockHelper { public v ...
- Hibernate映射文件详解(News***.hbm.xml)一
Hibernate是一个彻底的ORM(Object Relational Mapping,对象关系映射)开源框架. 我们先看一下官方文档所给出的,Hibernate 体系结构的高层视图: 其中PO=P ...
- 16.MindManager整理交互思路
点住主题同时按ins键可以插入一个支节点 右键主题选择下方的排列图表 可以选择排列方式 按住主题同时ctr+v就会粘帖成一个子主题 文本也可以复制黏贴 主题内容可以直接选择拖动更改结构 选择主题框上的 ...
- Visual Studio 2019使用docker开发(vsdbg的问题)
前言 vsdbg在国内下载的速度真的很慢,借助迅雷也没办法起飞. 这里还是来探讨下如何用迅雷进行下载以后安装操作. 遇到的状况 在使用Visual Studio 2019进行开发调试(https:// ...
- 学习python库:elasticsearch-py
一.介绍 elasticsearch-py是一个官方提供的low-level的elasticsearch python客户端库.为什么说它是一个low-level的客户端库呢?因为它只是对elasti ...
- 洛谷$P2824\ [HEOI2016/TJOI2016]$ 排序 线段树+二分
正解:线段树+二分 解题报告: 传送门$QwQ$ 昂着题好神噢我$jio$得$QwQQQQQ$,,, 开始看到长得很像之前考试题的亚子,,,然后仔细康康发现不一样昂$kk$,就这里范围是$[1,n]$ ...