由于 $\text{BJOI 2020}$ 因疫情停办,所以上次参加省选还是在初二的时候,岁月如烟,已然从非正式选手到正式选手了。

Day -?

高一开学搞了个 $CF$ 的新号,虽然没咋打比赛但题已经写了很多,基本上从 $2400\sim 3000$ 中顺着做,为了工整在省选前题目数达到了 $300$ 。

$ZR$ 的 $rating$ 也冲到 $2000$ 了,虽然还是很菜。

北京科协放送了四场免费的省选模拟赛,在我们学校举行,打的基本上都是暴力分,只有一场到了队线,感觉要完。

题目质量很高,教会了我基础容斥原理,谢谢 $dengls$ ,$dlstsdy$ !

Day 0 04/09

考前的最后一天拿出了寒假写的 $50+$ 页题目整理看了看,一看就是一天(因为有些题忘记咋做了),感觉愈发的紧张,毕竟是当前最重要的考试。

晚上在学校操场随机游走,放松了好久才得以缓解。

得知座位表是按照 $NOIP$ 考试成绩顺着排的,那么???离谱操作。

还发现 $xtq$ 与 $caoyue$ 被捆绑在一起,互搞对方心态(

得知座位后试了试键盘,感觉不错敲了敲板子就回家睡觉了。

曾经有一个时刻,我想复习一下支配树。

Day 1 04/10

省选一试。

拿到题后心情就舒缓了一点。先把三题都看了一遍,$A$ 感觉是个简单的送分题,$B$ 是个构造,$C$ 是个不太可做的图论题,于是决定顺序开题。

然后就去搞 $A$ 了,大概 $30\space min$ 就写完过拍了。

开了发 $B$ 题,看到 $m=2$ 送了 $30$ 分,就写了写,发现自己竟然不会第一个子任务 $n,m\leq 3$,这咋整?

于是打了打 $C$ 题送的暴力分,事实上写的时候我也不知道复杂度多大,$n\leq 10$ ,找个多项式做法就过去了(

回去想了想 $B$ 题,会了 $n=3,m=3$ 的 $\mathcal O(10^6)$ 的做法,冲了发,写了个拍子,调了调比赛就结束了。 感觉 $B$ 题细节好多。

预计得分 $100+50+16=166$ 。

Day 2 04/11

省选二试。

由于程序回收系统挂了,等了好久才拿到题。

开幕雷击,“支配”。

发现自己语文优秀,$A$ 题瞬间就看懂了,但发现自己不是很会做,$B,C$ 也是一样不太会做,感觉离退役不远了。

冷静下来发现 $A$ 是个诈骗题,冲了好久终于过拍了,看了一下时间过去了 $2$ 个多小时了。

发现 $B$ 的 $60$ 分是送的,那我还想正解?打打打。

发现 $C$ 的 $30$ 分是送的,那我还想正解?打打打。

于是就到了 $12:00$ 了,感觉自己这个分如果都得到了就挺高了就一直在检查自己的代码。 考后发现人均过 $A,B$ ,心态崩了。

预计得分 $100+60+30=190$ 。

发现初三和 $wxjor$ 都没有走,于是一起打 $generals$ 。鬼知道为啥能从一点打到六点的,从 $FFA$ 到 高中vs初中 ,手速惊人。

准备快乐 $whk$ 。

Day 3~6

回班上课,感觉文化课真的好玩儿。看了看数学/生物/物理,发现能听到老师在说啥了(

然而发现自己连二元二次方程都不会解了,更加神秘的是 $x+y=z\rightarrow z=-x-y$ 。

(化学太难了)

感觉同学都好强,又要被吊打了。

周四中午吃完饭后发现 $wxjor$ 在操场踢球,问了下是否出成绩了,他说我差不多进队了???就去实验楼问了问老师,得知一分没挂 $100+50+16+100+60+30=356$ 。

发现自己进省队了,震撼。中午本身要去自习也没什么心情了。

于是下午就开始摸鱼,生物课讲到一半掉线了,化学课就翘掉去机房玩了(化学太难了)。

Day 7~INF

开始多校联训,外省 $dalao$ 恐怖如斯,被吊打了。

Day 12 04/21

正式出榜,成为省队选手中省选分最低的,幸亏有 $NOIP$ 拉我一把。 

$wxjor$ 惜败 $caoyue$ ,成为 $B$ 队队长,$ysf$ 省队线下第一名,十分可惜。

感想

事实证明考前写板子是没有用的,因为啥都没考,最难的算法仅是主席树。

每天的策略都有问题,两天 $C$ 题思考时间均不超过 $10$ 分钟,导致这两题基本上是省队/学校中的最低分。

自己思维能力还是太弱了,两天的 $B$ 题均为中档题却均打的暴力分。

唯一良好的是每天的 $A$ 题都过了,而且最终预期分等于实际得分,没有挂分。

$\text{NOI 2021}$ 加油!


 

卡牌游戏

题意

有 $n$ 张卡牌,第 $i$ 号卡牌正面为 $a_i$ ,反面为 $b_i$ ,开始时均正面朝上。可以选择翻 $m$ 次,最小化极差。

$3\leq n\leq 10^6$ 。

题解

将 $a,b$ 放在一起排序,枚举最大值,那么只要选取一段区间使得每个元素在其中均有,且能选 $a$ 就选 $a$ ,选 $b$ 不能超过 $m$ 个。

上述过程可以 $\text{two pointers}$ 优化 ,时间复杂度 $\mathcal O(n\log n)$ 。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<climits>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
    int f=1,ans=0; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return f*ans;
}
const int MAXN=2e6+11;
int N,M,A[MAXN],B[MAXN],tot; pii tmp[MAXN];
bool cmp(pii x,pii y){return x.fi<y.fi;}
int vis[MAXN];
bool calc(int k){
    int l=1; int Minn=INT_MAX;
    for(int i=1;i<=tot;i++){
        while(l<=tot&&tmp[l].fi<tmp[i].fi-k) ++l;
        for(int j=1;j<=N;j++) vis[j]=-1;
        for(int j=l;j<=i;j++){
            int id,w;
            if(tmp[j].se<=N) id=tmp[j].se,w=0;
            else id=tmp[j].se-N,w=1;
            if(vis[id]==-1) vis[id]=w;
            else if(!w) vis[id]=0;
        }
        int res=0; bool ff=0;
        for(int j=1;j<=N;j++){
            if(vis[j]==-1){ff=1;break;}
            res+=vis[j];
        }
        if(ff) continue;
        Minn=min(Minn,res);
    }return Minn<=M;
}
int num[MAXN],cnt,sum;
void del(int x){
    int id,w;
    if(tmp[x].se<=N) id=tmp[x].se,w=0; else id=tmp[x].se-N,w=1;    
    if(num[id]==2){if(!w) sum++; num[id]--;}
    else if(num[id]==1){cnt--; if(w) sum--; num[id]--;}
    return;
}
void ins(int x){
    int id,w;
    if(tmp[x].se<=N) id=tmp[x].se,w=0; else id=tmp[x].se-N,w=1;
    if(num[id]==0){cnt++;if(w) sum++; num[id]++;}
    else if(num[id]==1){if(!w) sum--; num[id]++;}
    return;
}
bool calc1(int k){
    int l=1; int Minn=INT_MAX;
    memset(num,0,sizeof(num)); sum=0,cnt=0;
    for(int i=1;i<=tot;i++){
        ins(i);
        while(l<=tot&&tmp[l].fi<tmp[i].fi-k) del(l),++l;
        if(cnt==N) Minn=min(Minn,sum);
    }return Minn<=M;
}
int main(){
    freopen("card.in","r",stdin);
    freopen("card.out","w",stdout);
    N=read(),M=read(); 
    for(int i=1;i<=N;i++) A[i]=read(),tmp[++tot]=mp(A[i],i);
    for(int i=1;i<=N;i++) B[i]=read(),tmp[++tot]=mp(B[i],i+N);
    sort(tmp+1,tmp+tot+1,cmp);
    int l=1,Minn=INT_MAX;
    for(int i=1;i<=tot;i++){
        ins(i);
        while(l<=i){
            del(l); if(cnt==N&&sum<=M){l++;continue;}
            ins(l); break;
        }
        if(cnt==N&&sum<=M) Minn=min(Minn,tmp[i].fi-tmp[l].fi);
    }
    printf("%d\n",Minn); return 0;
}/*
6 3
8 11 13 14 16 19 
10 18 2 3 6 7 
*/
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-06
猜你喜欢
  • 2022-12-23
  • 2021-09-25
  • 2021-09-20
  • 2021-11-11
  • 2021-09-05
  • 2021-09-20
  • 2021-12-07
相关资源
相似解决方案