CSP2020 游记

考前一周

就完全学不太进去文化课了

然后特别想停课但是不行

结果每天翘着作业苟机房,被老师在后面喊打文化课笔记没整呀这样子

Day 0

早上学了一节物理和语文课

(结果考试语文年级 \(5001\) 名)

接着拿上了东西就出发了

在去德州的大巴上一直和 \(An\_Fly\) 聊天

到车站面到了 \(hzoi2019\) 和换了发型的 \(skyh\)

晚上打了牛客,\(orz\ happyguy\) \(1A\) 下凸包

Day 1

上午学了四毛子算法,颓过了 \(Loj6499\)

下午开幕雷击:又是题面非常长的题目,冷静读完发现是大模拟

诶我手动模拟日期我会呀,那咱先写个暴力模拟跳日期

写完之后就发现每四百年有一样的日期,那就开冲,大概写了两个多小时写完了,没测大样例就和暴力拍上来

然后看看这个 T4,这个 \(n^2\) 很容易啊,搞个 \(dfs\) 就行了呀,写完 \(dfs\) 之后发现 \(bool\) 返回值如何处理自己写之前并没有想清楚

结果 \(20\) 跑路了

这时候距离考试结束还有约一小时,然后把T2写上去,但是没发现可以与到一起做,所以复杂度带 \(\log\)

中间反复确认是不是需要读入 \(q_i\),最后决定还是读上,还手写二分代替 \(lower\_bound\) 来离散化

一贯 #define int long long 的我开了 ull 就走人了显然没注意到 \(2^{64}\) 的问题

中间发现居然还有 大样例,测了一下过拍的 T1 发现不行???

冷静下来发现答案差 1 天,又改了改就好了

最后读完这个 T3 还剩下 \(10\) 分钟,冲了最裸暴力就检查文件跑路了

出场发现有不少人会这个 T3,T2 还得判 \(2^{64}\) ,心情瞬间废掉了

不过测了一下 T1 没挂,让心态稳健了一些

出分是 100+95+30+20

技术总结

  • 如果要求 \(2^{64}-1\) 可以写 ull x=-1;

  • 函数调用

    发现这个调用肯定是个 \(DAG\)

    按照一些做法就是加法直接跟着后面的乘法做

    那么先统计所有序列里面的乘法量,然后拓扑标记和方案

  • 贪吃蛇

    我们发现这里的最大最小值用 \(set\) 维护一下

    然后把所有的蛇吃的情况模拟出来之后逆序扫一下,如果发现不满足的之际把后面的都置空

    那么这样的做法是 \(O(Tn\log n)\)

    然后发现后面的扫是不能降复杂度或者得到更好的做法

    那么优化前面求最大最小值的部分


以下参考了 \(EI\) 博客

考虑最大值和最小值的改变

如果 \(a_n\ge 2 a_1\) 那么最小值肯定是 \(min(a_2,a_n-a_1)\)

这时候就按照 \(NOIP2016\) 蚯蚓的套路来进行维护俩单调队列即可

单调性请自行证明

如果 \(a_n\le 2 a_1\) 那么就先将已经维护的两个队列归并一下,这部分可以做到 \(O(n)\)

因为减掉之后\(a_n-a_1<a_2\) 那么直接成为最小值就行了

不难证明剩下吃的都是小于 \(a_2\) 的量

如果最后剩下很多值都是\(a_1\) 但是 \(id\) 不同,模拟情况即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define reg register
inline int read(){
    int res=0,f=1; char k;
    while(!isdigit(k=getchar())) if(k=='-') f=-1;
    while(isdigit(k)) res=res*10+k-'0',k=getchar();
    return res*f;
}
const int N=1e6+10;
struct node{
    int v,id;
    bool operator<(const node &a)const{
        if(v^a.v) return v<a.v;
        return id<a.id;
    }
    bool operator ==(const node &a)const{return v==a.v&&id==a.id;}
}p[N],q1[N],q2[N],q3[N];
bool fl[N],vis[N];
int pre[N],n,s1[N],s2[N],cnt,a[N],t1,t2,t3,h1,h2,h3;
inline int size2(){return t2-h2+1;}
inline int size1(){return t1-h1+1;}
inline void EI_method(){
    memset(vis,0,sizeof(vis));
    int mnv=q3[h3].v; vis[q3[h3].id]=1;
    int id=1,fp=1;  while(fp<=t3&&q3[fp].v==mnv) vis[q3[fp].id]=1,++fp;
    while(!vis[id]) ++id; node tmp=(node){-1,-1};
    for(reg int i=t3;i>=fp;--i){
        s2[++cnt]=q3[i].id;
        if(tmp.id!=-1){
            s1[cnt]=tmp.id;
            if((node){q3[i].v-tmp.v,q3[i].id}<(node){mnv,id}) tmp=(node){q3[i].v-tmp.v,q3[i].id};
            else vis[q3[i].id]=1,tmp.id=-1,tmp.v=-1;
        }else{
            s1[cnt]=id; vis[id]=0; 
            while(id<=n&&!vis[id]) ++id; 
            tmp=(node){q3[i].v-mnv,q3[i].id};
        } 
    }
    if(tmp.id!=-1&&tmp.v==mnv){
        id=tmp.id; tmp.id=-1; tmp.v=-1; 
        vis[id]=1;    
    }
    if(tmp.id!=-1){
        for(reg int i=n;i>=1;--i){
            if(vis[i]) s1[++cnt]=tmp.id,s2[cnt]=i,tmp.id=i;
        }
    }else{
        for(reg int i=n,cur=0;i>=1;--i){
            if(!vis[i]) continue; cur^=1;
            if(cur){
                if(tmp.id!=-1) s1[++cnt]=tmp.id,s2[cnt]=i; 
                tmp.id=i; 
            }else s1[++cnt]=i,s2[cnt]=tmp.id; 
        }
    }return ;
}
inline void work(){
    h1=1; t2=n; h2=n+1; t1=0; cnt=0;
    memset(fl,0,sizeof(fl));
    for(reg int i=1;i<=n;++i) q1[++t1]=p[i]=(node){a[i],i};
    for(reg int i=1;i<=n;++i){
        node mx=(node){-1,-1},mn=(node){9e18+10,9e18+10};
        if(size1()) mx=max(mx,q1[t1]),mn=min(mn,q1[h1]);
        if(size2()) mx=max(mx,q2[t2]),mn=min(mn,q2[h2]);
        if(mx.v<mn.v*2){
            h3=1; t3=0; 
            while(size1()&&size2()){
                if(q1[h1]<q2[h2]) q3[++t3]=q1[h1++];
                else q3[++t3]=q2[h2++];
            } 
            while(size1()) q3[++t3]=q1[h1++];
            while(size2()) q3[++t3]=q2[h2++];
            EI_method();
            break;
        }else{
            s1[++cnt]=mn.id; s2[cnt]=mx.id;
            if(size2()&&mx==q2[t2]) t2--; else t1--;
            if(size2()&&mn==q2[h2]) h2++; else h1++;
            q2[--h2]=(node){mx.v-mn.v,mx.id};
        } 
    }
    int las=n; 
    for(reg int i=1;i<=n-1;++i) fl[s1[i]]=1;
	for(reg int i=n-1;i>=1;--i){
		if(fl[s2[i]]){
			while(las>i) fl[s1[--las]]=0;
		} 
	}printf("%lld\n",n-las+1); 
	return ;
}
signed main(){
    int T=read(); T--;
    n=read(); for(reg int i=1;i<=n;++i) a[i]=read(); work();
    while(T--){
        int pos,v,siz=read();
        while(siz--) pos=read(),v=read(),a[pos]=v;
        work();
    } return 0;
}```
posted @ 2020-11-12 21:34  yspm  阅读(249)  评论(3编辑  收藏  举报