NOIP2018游记

CCF-NOIP-2018 提高组 游记

\(6\) 个参加 NOIP 的年头了吧,更多的是一份冷静,似乎已经习惯了考场的气氛了吧。
反正 Noi 也去过了,临场心态应该算非常好吧。
复赛在自己学校考,也算是一个额外buff吧。

Day -1

早上是学长的比赛,成功爆的很惨(没对拍+不认真)。根据RP守恒以及分数守恒,但愿NOIP会考得不错了吧。(++RP)

下午随便放了一套毒瘤数据结构给学弟做,然后自己开始快乐划水(--RP)。

Day 0

早上快乐睡觉,下午快乐拿完准考证之后,用 \(python\)\(tkinter\) 写了个祝(du)福(nai)自己AK NOIP 的 \(GUI\)

import tkinter
import tkinter.messagebox

main = tkinter.Tk()

main.title("Best Wishes to You!")

Name = tkinter.StringVar()

def putresult():
    global Name
    tkinter.messagebox.showinfo("祝福", "Wish" + Name.get() + "can AK Noip.")

NameLabel = tkinter.Label(main, text = "请输入你的名字")
NameInput = tkinter.Entry(main, textvariable = Name)
Button = tkinter.Button(main, text = "Best Wishes", command = putresult)


NameLabel.pack()
NameInput.pack()
Button.pack()

main.mainloop()

晚上快乐和小姐姐聊天,小姐姐给自己上了个buff(buff += 1e9),然后11点的时候被小姐姐赶去碎觉orz,结果睡不着。。
(考前综合症。。)

Day 1

1点才勉强入睡,6点就醒了。。。(考前综合症x2)
次完早餐快乐骑车上学(大雾),穿着校服当然就不用在校门口等啦,进了学校以后快乐在润德楼前广场的水池了洗手(蜜汁信仰,buff++)

进入考场,被分到了 win 10 机房...(键盘虽然软的不行,但是mac选手无所畏惧。。)座位在第一排正门口。。感觉自己 buff--

Day1 password = "Fei2Xue@Lian$Tian!" 有点小难受。。

开始看题,T1 看起来很像积木大赛。。几经测试以后,发现真的就是个积木大赛,小声嘀咕了一句“沙雕原题”就开始敲,结果忘记了简单的差分做法,愣是写了个单调栈上去,感觉自己学傻了。。

码了个对拍上去,顺便看了后面的题,此时过去了15min。。

看T2,怎么tmd是个“大凯的疑惑”,瞄一眼数据范围,然后手动观察了一波大样例,大胆猜想所能使用的货币一定是原货币系统的子集,稍加证明就敲了个简单的完全背包上去,1A,开始做T3。此时时钟指向了9点。。

发现T3题意是给定一棵树,求 \(m\) 个边不交的链,使得最短链长度最大。

先无脑套了个二分模型上去,然后去上洗手间开始想怎么贪心。

随便脑补了一下发现可以用std::multiset解决,测了大样例,手造了几个小数据过了就不管了。似乎半场AK了,而且由于看到了CCF突然更新了机器配置,对自己使用STL的大常数没有任何担心。。。(++flag)

后半场在快乐小恐龙,顺便用tkinter写了个 a+b 的GUI。

出考场以后全都在喷原题大赛,学弟似乎AK的也不少,附中的胜利?

Day1
估分 100+100+90~100 = 290~300
自测 100+100+95~100 = 295~300
实际 ? + ? + ? = ?

下午和小gaigai聊了一会天,小gaigai又给我上了个buff(buff += 5e8),就开始快乐划水了(--RP)。

Day 2

Day1 晚上睡得挺香的,这天起来的时间也比较normal,感觉精神状态还ok。唯一可惜的是进考场没有和小gaigai聊天。(buff--)

感觉今天题目会特别难,考前在休息室里睡了一会儿。

Day2 Password = "%xiao#SHU!shen9XIA" 难受x2

看了一眼题,一开始以为T1就完全不可做,然后认真一看发现是个基环树最小字典序遍历(Noip怎么会考基环树?????)

敲了个std::vector然后就开始暴力删边跑,感觉自己成功从毒瘤卡常选手变成了毒瘤STL大常数选手(TLE++)

时间过去了半个小时。

看了一眼T2发现一点头绪都没有,手算3 3 得出了个144开始mengbier,构造出了一个反例发现自己不知道该干啥了,敲了50分就先去看T3了

发现T3是个没有上司的舞会动态版,开始骂街“Noip怎么会考树形DDP,艹了”,想起来考前自己给学弟搬了无数道树形DP/换根DP,还出了个最小带权树上支配集,瞬间感觉自己押题能力++

看了一眼部分分发现只有4个点需要DDP,虽然有大致的对于DDP的概念,但是由于没写过DDP所以根本不敢写,写了84分的部分分,这里可以简单介绍一下做法:
首先对于小数据(44pts),我们发现可以直接暴力解决,但是如果只会暴力的话,这道题的分数也就止步于此了,我们不妨考虑强制(不)选择一个点的影响,显然会影响这个点到根节点的链的答案,发现可以直接暴力修改贡献即可。这样做的话可以顺便把B1的部分拿了,总计52pts。

//dpc: each query's DP value dp:Basic state's DP value
inline void upd(int x, bool p, int y, bool q) {
	dpc[x][1 - p] = 1e12, dpc[y][1 - q] = 1e12;
	while (x != y) {
		if (dep[x] < dep[y]) std::swap(x, y);
		dpc[fa[x]][0] += dpc[x][1] - dp[x][1];
		dpc[fa[x]][1] += std::min(dpc[x][1], dpc[x][0]) - std::min(dp[x][0], dp[x][1]);
		x = fa[x];
	}
	while (x != 1) {
		dpc[fa[x]][0] += dpc[x][1] - dp[x][1];
		dpc[fa[x]][1] += std::min(dpc[x][1], dpc[x][0]) - std::min(dp[x][0], dp[x][1]);
		x = fa[x];
	}
}

inline void rmv(int x, int y) {
	while (x != y) {
		if (dep[x] < dep[y]) std::swap(x, y);
		dpc[x][0] = dp[x][0];
		dpc[x][1] = dp[x][1];
		x = fa[x];
	}
	while (x != 1) {
		dpc[x][0] = dp[x][0];
		dpc[x][1] = dp[x][1];
		x = fa[x];
	}
	dpc[1][0] = dp[1][0], dpc[1][1] = dp[1][1];
}

接下来我们考虑特殊性质,发现性质1和性质2本质上只需要考虑一个点强制被(不)选的状态(性质2两个相邻点的贡献很好考虑),我们不妨考虑令每一个点为整棵树的根时候的答案,发现可以用一个简单的换根DP实现,问题直接解决了。这部分一共有40pts。

//dpa: value of each vertex as the root
void dfs2(int u, ll dp0 = 0, ll dp1 = 0) {
	dpa[u][0] = dp[u][0] + dp1;
	dpa[u][1] = dp[u][1] + std::min(dp0, dp1);
	for (R Edge *e = hd[u]; e; e = e -> nxt) {
		R int v = e -> to;
		if (v == fa[u]) continue;
		dfs2(v, dpa[u][0] - dp[v][1], dpa[u][1] - std::min(dp[v][0], dp[v][1]));
	}
}

这样就可以轻松获得84分了,这部分代码总共敲了我半小时左右。性价比相比于树链剖分+线段树维护转移矩阵的DDP写法要高不少。

这个时候距离考试结束大约还有1.5小时,可是我T2的暴力毫无头绪一点想法也没有,也没有推出性质,感觉自己实力还是差了一些。

最后也就以这样的成绩草草收场了。

Day2
估分 88100+5055+84~92 = 222~247
自测 88100+5055+84~88 = 222~243
实际 ? + ? + ? = ?

posted @ 2018-11-16 14:54  Melacau  阅读(440)  评论(0编辑  收藏  举报