CSP2023 游记

CSP2023 游记

本来是写游记,现在发现好像成了复习博客。

Day -3

上午打了一场模拟赛,又垫底了。

好像是信心赛,但是只会前两道(恼了!)。

发现 accoders 在 CSP 前两天还有模拟赛,悲。

复习 Tarjan

注意:Tarjan 题目常见图不连通情况。

  • low[u] 表示以 \(u\) 为根的子树中结点以及这些结点通过一条非树边能到达的结点的最小 dfn

有向图:

  1. 强连通分量:low[x] == dfn[x]

有向图中两个顶点可以互相到达,称为他们强连通;强连通分量是有向图的极大强连通子图。

一张图中所有强连通分量缩点后得到一个 DAG;设出度为 \(0\) 的点数为 \(x\),入度为 \(0\) 的点数为 \(y\),那么将一张 DAG 修改为一个强连通分量至少要加 \(\max \left\{x,y \right\}\) 条边。

void dfs(int x) {
	tot ++;
	dfn[x] = low[x] = tot;

	st.push(x);
	vis[x] = 1;

	for(int i = h[x];i;i = e[i].next) {
		int to = e[i].to;

		if(!dfn[to]) {
			dfs(to);
			low[x] = min(low[x],low[to]);
		}
		else if(vis[to])
			low[x] = min(low[x],dfn[to]);
	}

	if(low[x] == dfn[x]) {
		int res = 0;

		while(true) {
			res ++;
			int t = st.top();
			vis[t] = 0;
			st.pop();

			if(t == x)
				break;
		}

		if(res != 1)
			ans = min(ans,res);
	}
}

强连通分量一般用于缩点,例如受欢迎的牛。

无向图:

  1. 割点:dfn[x] <= low[to]

由于 low[u] 可以理解为 \(u\) 子树中的点通过一条非树边能回溯到的最小 dfs 序,那么如果某个结点 to 不能回溯到 x 或其之前结点,点 \(x\) 为割点。

void dfs(int x,int fa) {
    // fa 表示父节点,用于判断根节点的 
    tot ++;
    dfn[x] = low[x] = tot;
    
    int child = 0;
    // 存该节点的子树个数,用来判断根节点是否为割点

    for(int i = h[x];i;i = e[i].next) {
        int to = e[i].to;
        if(!dfn[to]) {
            dfs(to,fa);
         
            low[x] = min(low[x],low[to]);
            
            if(low[to] >= dfn[x] && x != fa)
                cut[x] = 1;// 标记为割点
                // 这里特判了不是根节点 
            
            if(x == fa)
                child++;// 记录子树
        }

        low[x] = min(low[x],dfn[to]);
    }

    if(x == fa && child >= 2)
        cut[x] = 1;
        // 是根节点并且有两个或以上的子树
        // 一定是割点 
}
  1. 割边:dfn[x] < low[to]

注意区分割边与割点的判断条件,当 dfn[x] == low[to] 时,\(x\) 是割点,但 \((x,to)\) 不是割边。

求割边不需要考虑根的情况。

Day -2

上午打了一场模拟赛,又垫底了。

横叉边有个性质:存在横叉边 \((u,v)\) 当且仅当 \(v\) 可到达 \(\operatorname{lca}(u,v)\)

圆方树

广义原方树把点双看作方点,点看作圆点。

实际上是将点双内的边缩成一个方点,再从该方点向点双内其他点连边。

这样得到一棵树。

圆方树可以描述两点之间路径必经结点,原图任意两点之间所有割点等。

每个点双实际上缩成了以方点为中心点的菊花图,各个点双之间以割点相连。

一些性质:

  • 圆点 \(x\) 的度数等于包含它的点双个数。
  • 原图上直接相连的 \(u,v\) 包含于同一点双。
  • 圆点 \(x\) 是叶子当且仅当它在原图不是割点。
  • \(x,y\) 简单路径上的所有圆点恰好是原图 \(x,y\) 之间的所有必经点。

这些性质实质上表达的就是,圆方树完整地保留了原图的必经性。

晚上刷了一堆板子,打算明天模拟赛继续刷板子。

Day -1

上午打了一场模拟赛,又垫底了。

第一题签到题,签了个道就走人了。

考虑写点双、边双模板。

  1. 点双联通分量:不存在割点的极大子图

孤立的一个点也是点双。

\(x\) 为割点时弹栈,栈顶到 \(to\) 都属于这个点双,割点也属于这个点双。

割点可能在多个点双内,不能弹栈;\(to\) 的子树内所有点双都处理了就可以弹。

void dfs(int x,int root) {
    tot ++;
    dfn[x] = low[x] = tot;
    st[++top] = x;

    if(x == root && h[x] == 0) {
        num ++;
        ans[num].push_back(x);

        return ;
    }
    
    for(int i = h[x];i;i = e[i].next) {
        int to = e[i].to;

        if(!dfn[to]) {
            dfs(to,root);

            low[x] = min(low[x],low[to]);

            if(low[to] >= dfn[x]) {
                num ++;
                int k;

                do {
                    k = st[top];
                    top --;
                    ans[num].push_back(k);
                }while(k != to);

                ans[num].push_back(x);
            }

        }
        else
            low[x] = min(low[x],dfn[to]);
    }
}
  1. 边双联通分量:不存在割边的极大子图

考虑寻找割边,删去割边后剩下的若干个连通块实质上就是所有边双。

注意考虑重边的问题,两个点之间有重边也算边双。所以就不能像之前一样判点了,要判断边是否走过。

// cnt 初始赋为 1,fa 传 0
void dfs1(int x,int fa) {
    tot ++;
    dfn[x] = low[x] = tot;
    st[++top] = x;
    
    for(int i = h[x];i;i = e[i].next) {
        int to = e[i].to;

        if(!dfn[to]) {
            dfs1(to,i);

            low[x] = min(low[x],low[to]);

            if(low[to] > dfn[x]) 
                cut[make_pair(x,to)] = cut[make_pair(to,x)] = 1;
        }
        else if(i != (fa ^ 1))
            low[x] = min(low[x],dfn[to]);
    }
}

void dfs2(int x) {
    vis[x] = 1;
    ans[num].push_back(x);
 
    for(int i = h[x];i;i = e[i].next) {
        int to = e[i].to;

        if(vis[to] || cut[make_pair(x,to)])
            continue;
        
        dfs2(to);
    }
}

打了一遍树剖,写成 tag\(0\)Pushdown 了,恼。

下午接着打点分治。

Day 0

不跑操 + 提前发手机,直接双喜临门。

看大纲发现平衡树是提高组内容,临时复习 FHQ-Treap。

从上午出发就开始摆,一点板子没看。

看 Hanzelic 用 4080 + 13 代 i9 的电脑玩原神,莫名感觉有点浪费。

不知道为什么,在天津附近时,Phigros 会出现神奇杂音,感觉可能是某个频段的信号干扰。

可能是因为波波走了,今年没有看海环节。

连续两次点外卖被教练发现,寄。

Day 1

上午教练没发手机,Trump_ 过来打了一会儿钢 4,然后刷 b 站刷到 12:00。

中午睡了一会,但仍然很困,考虑喝咖啡度过下午。

来到考场,发现隔壁 win10,而我这场是 win7,燕大的垃圾电脑只有 4GB,虚拟机的屏幕尺寸也不对,十分的糊。

赛时脑子里一直单曲循环《白骨》的 Hook 部分。

《白骨》 在那白虎岭有一位白骨精

她是来无影那变化还无定

在那白虎岭你绝不该独行

等到她来捕命你太不幸

在那白虎岭有一位白骨精

她是来无影那变化还无定

在那白虎岭她有千百副型

你让她乖不行她才不听

Verse:

她本是孤魂野鬼该没于滚滚黄泉

偶采得天地灵气才化形醒于长眠

本已是大运加身又难耐心中贪念

总想个不劳而获对唐僧无比垂涎

但奈何唐僧身边护着一位孙悟空

这齐天大圣可和等闲护卫很不同

若强取身上得被捅上几个深窟窿

要使点计谋才能化被动为主动

她先变一位妙龄少女来取得信任

哭诉自己悲惨的遭遇惹唐僧愤懑

再化身一位婆婆讲述两句公道话

抛开现实不谈孙猴你为何凶暴她

她转眼变成一位手持佛珠的老翁

我原谅她的错了闭上你的追讨声

这泼猴胡搅蛮缠丝毫不怜悯呼救

唐长老请勿徘徊念出你的紧箍咒

在那白虎岭有一位白骨精

她是来无影那变化还无定

在那白虎岭你绝不该独行

等到她来捕命你太不幸

在那白虎岭有一位白骨精

她是来无影那变化还无定

在那白虎岭她有千百副型

你让她乖不行她才不听

Verse:

她将蜈蚣毒虫精心包装塞入青砂罐

“施主这都是斋饭”她打开请他看

她知道自己法术低劣骗不过火眼金睛

只需骗过唐僧就能转移矛盾引起纷争

死在金箍棒下的只是一副皮囊

这皮囊她还能变出千千万万具

互相猜疑谨慎恐惧才是她的力量

只需等待四人分崩离析散乱去

假装死亡她就能收获哀悼叹惋

作恶既往不咎她还能保住饭碗

等到风头一过她就照常略施粉黛

总归还有愚笨唐僧继续送上门来

唐僧错了吗孙大圣又错了吗

究竟是什么造就了如此冷漠的他

请将你们紧紧掐住对方的双手松开

齐心击溃这白骨就莫怕妖雾重来

Hook:

在那白虎岭有一位白骨精

她是来无影那变化还无定

在那白虎岭你绝不该独行

但只需态度硬她就步入困境

在那白虎岭有一位白骨精

她是来无影那变化还无定

在那白虎岭她有千百副型

只需信赖笃定她就无处遁形

T1 读题直接读错,我还以为旋转的幅度只能为 \(1\),结果样例输出 \(26\)

一直读错题导致花了 \(50\) 分钟才写完 T1。

T2 先无脑打了个 \(O(n^2)\) 上去,想先看看后面。

T3 大模拟???直接就冲着部分分打了,一直在调 4 操作的二分,但赛后发现好像直接暴力枚就行,不用二分。

T4 本来想打一个 \(c_i=0\) 的点,胡完发现大样例过不去,直接摆。

估计只有 \(150\) 分,严格低于预期。

出来之后发现大家好像都很寄,心里平衡了一些

后面是两天的假期,不能被小小的 CSP 影响了假期的心情。

posted @ 2023-10-20 09:11  -白简-  阅读(117)  评论(2编辑  收藏  举报