NOIP2018游记

前言

过去大半个月才写游记确是有点……
只能根据残存的记忆来写了。

D a y   0 : 11.9 Day\ 0:11.9 Day 0:11.9

周五早上七点多到机房,既有颓废的巨佬,又有拼命打板子的蒟蒻。我显然是后者,打了几个KMP之类的板子后突然就 10 10 10点了。于是我们也就踏上了去杭州之路。
今年六月,我们曾参加学校组织的活动,去杭州游玩,曾住在一个豪华酒店——的对面。而那个豪华酒店正是我们这次NOIP时住的酒店,真是机缘巧合!

下午去XJ领个参赛证,顺便逛了一下(毕竟我们是旅游团,初中三年都未曾外出过)
在这里插入图片描述
在这里插入图片描述

晚上当然是颓废,为了第二天的考试调整心态。炉石破亿五包没有开出什么好东西,感觉怒赞了一波欧气。

晚上老叶还讲了考试的技巧,当然那些东西都是人尽皆知的,没什么意义。但是考场上能不能做到,还得看心态。

D a y   1 : 11.10 Day\ 1:11.10 Day 1:11.10

早上向高二的大佬们请教了上界NOIP的心路历程。他们许多人的观点都是:打好暴力,一定要A掉第一题。

8 : 30 8:30 8:30

拿到第一题,我一下就惊呆了,这题和NOIP2013积木大赛有什么区别?直接秒掉。

然后就是T2,分析了一波样例,一下就发现了性质。显然先sort一遍,然后做个完全背包,没出现的数就统计入答案,并在完全背包里更新上有关的点即可。

半个小时我就写好了两题,并过了大样例。

9 : 20 9:20 920

T3可把我难住了,我开始想了一下贪心,可是没什么思路。DP更是不知道怎么转移。然后我又往数据结构上面想,好像树剖什么的都还是不可做。

再我也没办法了。时间一分一秒的流逝,转眼就到了 10 : 00 10:00 10:00。与其在这里敲冰求火,不如先骗分。好在此题的部分分甚多。写完这题的部分分,我还有一个小时的时间。吃完了面包,我就开始写前两题的对拍,保证前两题不出错。

就这样D1结束了。时钟转到 12 : 00 12:00 12:00的那一刻我还自我感觉良好,感觉 255 255 255分还是挺稳的。但是下一秒我就傻眼了,我听到了边上几位大佬的对话:“这题目怎么这么水?我一个半小时就AK了”“这试卷太水了,三道都是原题,我全都做过!”听到他们的话,我的内心是崩溃的:出题人你抄NOIP2013也就算了,居然出三道原题。这种试卷绝对有一堆人AK,我 255 255 255直接凉掉。

悲伤的氛围立刻笼罩上来,下午我呆坐在宾馆里。我的室友同样也是 255 255 255,他的内心似乎没什么扰动,在问候了出题人一波祖宗之后就立刻"上马"(跟别人LOL)了。然而我的内心却平静不下来,更糟糕的打炉石的时候是我居然开出一张霍格,直接败了一大波人品,吓得我炉石都不敢玩了。

没事干就只能去串门,YPC的父母来了,不好去他的房间。于是我就去老爷子的房间,他在看电影。有取了 x o r xor xor a n t i q u a l i t y antiquality antiquality的房间,他们一个在颓废,另一个在看他颓废。可是我又没有任何颓废的动力,又没有任何写题的动力。只能呆坐在房间里。呆坐了一个下午。

唯一然我欣慰的是我找到了《林中路》、《非此即彼》等书的PDF文件。以后想颓的时候可以看这些书颓(虽然我也看不懂)。但是今天我是肯定不会看的。

晚上心情终于有了平复,YPC的父母走了,于是我就去他房间颓,看他打彩6。我突然感觉这颓废的时光很幸福,这时光可能成为我许久的记忆。似乎做每件事都是值得的。我们七八个人合资叫了外卖,我下去拿的时候忘了带电梯卡了,只能跑上 11 11 11楼,感觉整个人腿都快断了,不过心中的悲伤之情有了缓解。

然而一种恐惧之情又涌上我的心头,我害怕,我拍D2我会考崩。虽然我并不怕退役,但是我还是害怕考崩。和老爸打了个电话,聊了20分钟,这种恐惧之情也得到了缓解。
在这里插入图片描述

D a y   2 : 11.11 Day\ 2:11.11 Day 2:11.11

不得不说,宾馆的早饭还是很好吃的。

大雾弥漫的杭州,似乎给考试增添了阴沉之气。
在这里插入图片描述

在这决定生死的D2之前的几个小时里,我的内心居然毫无波动。我是多么渴望现在已是 12 : 10 12:10 12:10,考试已经结束。可是现在就是 8 : 10 8:10 8:10,我还在考场外徘徊……

8 : 30 8:30 8:30

看到T1题面的时候,我的内心是崩溃的,看起来一点都不可做。我又去看了T2和T3的题面,T2显然也很不可做,T3至少有44分的暴力分。

当我细致的看完T2后,我发现并不是那么不可做,对于 m = = n − 1 m==n-1 m==n1的情况,直接一个贪心即可,每次选区字典序最小的那个点走即可。可是对于后面 m = = n m==n m==n的情况,我又不会做了。显然是要删去一条边,然而怎么删,我并看不出来。时间一下就到了 9 : 15 9:15 9:15,我感觉再这么死磕T1会出事,可是我的内心又想起了大佬们的话:“T1一定要A掉”。我的内心是那么的矛盾,既想刚出T1,又想去打T3的暴力。在那一瞬间,我感觉我的心态爆炸了。

我想起了老叶的那句话:心态不好的时候就去上厕所。于是我就上了个厕所,果然心态释然了许多。我决心去打T3的暴力。
打完T3暴力,已经接近十点了。我只拿了 104 104 104分,感觉还是很凉。

我突然又想,T2暴力dfs总是可以打的吧!于是又开始刚T2,果然打出了暴力,还找到了 65 65 65分的规律。管他对不对,先写上去再说!匆匆忙忙写完T2的65分,还剩一个小时多一点的时间,赶紧去做T1剩下的40分。

基环树怎么搞呢!搞不来!管他怎么做,暴力枚举删边然后当作一棵树来做总能拿很多分吧!唉,等等 n ≤ 5000 n\leq 5000 n5000,也就是 O ( n 2 ) O(n^2) O(n2)能过!也就是暴力删边就能过!那直接写啊!

就这样我写了T1剩下的 40 40 40分。离考试结束也只有十几分钟了,匆匆忙忙写了对拍,考试就结束了。

今天是我第一次没在过程中吃面包的考试,以前的NOIP,ZJOI,包括D1,我都是一拿到面包就吃掉的。而今天我却紧张的没敢吃。我有很多次都感觉自己凉了,因此上了大概 10 10 10次厕所。上厕所打法真的好啊!我觉得我能稳住心态不崩,全靠的是上厕所。

考试终于结束了,出来的时候,翔哥问我感觉怎么样,我说感觉挺难的,我最高分 209 209 209,最低就不知道了。


我最终的成绩是444。D1T3爆了20分,D1只有235,D2是我预测的209。还行吧,一等大概是苟住了。

这次NOIP,我觉得我最大的收获就是心态,我在D2考场上对心态的调整,绝对是我以后借鉴的对象。

下面是AC的代码,包括D2T3订正的代码。

D1T1:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int read(){
	char c;int x=0,y=1;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
	if(c=='-') y=-1;else x=c-'0';while(c=getchar(),c>='0'&&c<='9')
	x=x*10+c-'0';return x*y;
}
int n,a[100005];
ll ans;
ll solve(int l,int r,int Min){
	if(l>r) return 0;
	if(l==r) return 1ll*a[l]-1ll*Min;
	int b=2e9,p=0;
	for(int i=l;i<=r;i++)
	  if(a[i]<b) b=a[i],p=i;
	return 1ll*b-1ll*Min+solve(l,p-1,b)+solve(p+1,r,b);
}
int main()
{
	n=read();
	for(int i=1;i<=n;i++) a[i]=read();
	ans=solve(1,n,0);
	printf("%lld",ans);
	return 0;
}

D1T2:

#include<bits/stdc++.h>
#define MAXN 105
using namespace std;
int read(){
	char c;int x=0,y=1;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
	if(c=='-') y=-1;else x=c-'0';while(c=getchar(),c>='0'&&c<='9')
	x=x*10+c-'0';return x*y;
}
int T,n,ans,Max,a[MAXN],vis[70005];
int main()
{
	T=read();
	while(T--){
		n=read();ans=0;Max=0;
		for(int i=1;i<=n;i++) a[i]=read(),Max=max(Max,a[i]);
		sort(a+1,a+1+n);vis[0]=1;
		for(int i=1;i<=n;i++){
			if(vis[a[i]]) continue;
			ans++;
			for(int j=0;j<=Max;j++)
			   if(vis[j]&&j+a[i]<=Max) vis[j+a[i]]=1;
		}
		printf("%d\n",ans);
		for(int i=0;i<=Max;i++) vis[i]=0;
	}
	return 0;
}

D2T1:

#include<bits/stdc++.h>
#define MAXN 5005
using namespace std;
int read(){
	char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
	while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
void print(int x){
	if(x/10) print(x/10);
	putchar(x%10+'0');
}
int n,m,cnt,head[MAXN<<1],nxt[MAXN<<1],go[MAXN<<1];
int sta[MAXN],top,out[MAXN];
void add(int x,int y){
	go[cnt]=y;nxt[cnt]=head[x];head[x]=cnt;cnt++;
	go[cnt]=x;nxt[cnt]=head[y];head[y]=cnt;cnt++;
}
vector<int> q[MAXN];
namespace uck{   //前面省略的某个字母,你们肯定猜的出来。生动的反应了我考场上的心态。
	int vis[MAXN];
	void solve(int x){
		vis[x]=1;sta[++top]=x;int l=q[x].size();
		for(int i=0;i<l;i++){
			int a=q[x][i];
			if(vis[a]) continue;
			solve(a);
		}
	}
}
namespace ccf{
	int sta[MAXN][MAXN],top[MAXN],vis[MAXN];
	void solve(int x,int p,int p1,int p2){
		vis[x]=1;sta[p][++top[p]]=x;int l=q[x].size();
		for(int i=0;i<l;i++){
			int a=q[x][i];
			if(vis[a]) continue;
			if((x==p1&&a==p2)||(x==p2&&a==p1)) continue;
			solve(a,p,p1,p2);
		}
	}
	int cp(int x,int y){
		if(top[x]<n) return 1;
		if(top[y]<n) return 0;
		for(int i=1;i<=n;i++)
		  if(sta[x][i]!=sta[y][i]) return sta[y][i]<sta[x][i];
		return 0;
	}
	void compareit(){
		int l=1,r=2;
		while(r<=n){
			if(cp(l,r)) l=r;
			r++;			
		}
		for(int i=1;i<=n;i++) out[i]=sta[l][i];
	}
}
int main()
{
	n=read();m=read();
	memset(head,-1,sizeof(head));
	for(int i=1;i<=m;i++){
		int x=read(),y=read();
		add(x,y);q[x].push_back(y);q[y].push_back(x);
	}
	for(int i=1;i<=n;i++)
	 sort(q[i].begin(),q[i].end());
	if(m==n-1){
		for(int i=1;i<=n;i++) uck::vis[i]=0;
		uck::solve(1);
		for(int i=1;i<=top;i++) print(sta[i]),putchar(' ');
	}
	else{
		int p=1;
		for(int i=0;i<cnt;i+=2,p++){
			for(int j=1;j<=n;j++) ccf::vis[j]=0;
			ccf::solve(1,p,go[i],go[i^1]);
		}
		ccf::compareit();
		for(int i=1;i<=n;i++) print(out[i]),putchar(' ');
	}
	return 0;
}

D2T3:这是抄题解的,十分巧妙的一道题(貌似是动态打炮的裸题,绝望),我到时候会写题解。

#include<bits/stdc++.h>
#define MAXN 100005
#define ll long long
using namespace std;
const ll INF=1e18;
int read(){
	char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
	while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
void print(ll x){
	if(x/10) print(x/10);
	putchar(x%10+'0');
}
int n,m,ty,cnt,p[MAXN],head[MAXN<<1],nxt[MAXN<<1],go[MAXN<<1];
int F[MAXN][20],dep[MAXN];
ll dp[MAXN][2],f[MAXN][20][2][2];
void add(int x,int y){
	go[cnt]=y;nxt[cnt]=head[x];head[x]=cnt;cnt++;
	go[cnt]=x;nxt[cnt]=head[y];head[y]=cnt;cnt++;
}
void dfs(int x,int fa){
	F[x][0]=fa;dep[x]=dep[fa]+1;
	dp[x][1]=p[x];f[x][0][0][0]=INF;
	for(int i=1;(1<<i)<=dep[x];i++)F[x][i]=F[F[x][i-1]][i-1];
	for(int i=head[x];i!=-1;i=nxt[i]){
		int to=go[i];
		if(to==F[x][0]) continue;
		dfs(to,x);dp[x][0]+=dp[to][1];dp[x][1]+=min(dp[to][1],dp[to][0]);
	}
}
void calculate(int x){
	f[x][0][1][0]=dp[F[x][0]][0]-dp[x][1];
	f[x][0][0][1]=f[x][0][1][1]=dp[F[x][0]][1]-min(dp[x][0],dp[x][1]);
	for(int i=1;(1<<i)<=dep[x];i++){
		int mid=F[x][i-1];
		f[x][i][0][0]=min(f[x][i-1][0][0]+f[mid][i-1][0][0],f[x][i-1][0][1]+f[mid][i-1][1][0]);
		f[x][i][0][1]=min(f[x][i-1][0][0]+f[mid][i-1][0][1],f[x][i-1][0][1]+f[mid][i-1][1][1]);
		f[x][i][1][0]=min(f[x][i-1][1][0]+f[mid][i-1][0][0],f[x][i-1][1][1]+f[mid][i-1][1][0]);
		f[x][i][1][1]=min(f[x][i-1][1][0]+f[mid][i-1][0][1],f[x][i-1][1][1]+f[mid][i-1][1][1]);
	}
	for(int i=head[x];i!=-1;i=nxt[i]){
		int to=go[i];
		if(to==F[x][0]) continue;
		calculate(to);
	}
}
void work(int x,int a,int y,int b){
	if(dep[x]<dep[y]) swap(x,y),swap(a,b);
	ll u0=INF,u1=INF,v0=INF,v1=INF,l0=INF,l1=INF,ans=INF,lca;
	a?u1=dp[x][1]:u0=dp[x][0];b?v1=dp[y][1]:v0=dp[y][0];
	for(int i=17;i>=0;i--)if(dep[F[x][i]]>=dep[y]){
		ll wr=u1,un=u0;
		u1=min(wr+f[x][i][1][1],un+f[x][i][0][1]);
		u0=min(wr+f[x][i][1][0],un+f[x][i][0][0]);
		x=F[x][i];
	}
	for(int i=17;i>=0;i--)if(F[x][i]!=F[y][i]){
		ll wr=u1,un=u0,yn=v1,wc=v0;
		u1=min(wr+f[x][i][1][1],un+f[x][i][0][1]);
		u0=min(wr+f[x][i][1][0],un+f[x][i][0][0]);
		v1=min(yn+f[y][i][1][1],wc+f[y][i][0][1]);
		v0=min(yn+f[y][i][1][0],wc+f[y][i][0][0]);
		x=F[x][i],y=F[y][i];		
	}
	if(x==y){
		lca=x;b?l1=u1:l0=u0;
	}
	else{
		lca=F[x][0];l0=dp[lca][0]-dp[x][1]-dp[y][1]+u1+v1;
		l1=dp[lca][1]-min(dp[x][1],dp[x][0])-min(dp[y][1],dp[y][0])+min(u0,u1)+min(v1,v0);
	}
	if(lca==1) ans=min(l0,l1);
	else{
		for(int i=17;i>=0;i--)if(dep[F[lca][i]]>1){
			ll wr=l1,un=l0;
			l1=min(wr+f[lca][i][1][1],un+f[lca][i][0][1]);
			l0=min(wr+f[lca][i][1][0],un+f[lca][i][0][0]);
			lca=F[lca][i];
		}
		ans=min(dp[1][0]-dp[lca][1]+l1,dp[1][1]-min(dp[lca][1],dp[lca][0])+min(l0,l1));
	}
	if(ans>=INF) puts("-1");
	else print(ans),puts("");
}
int main()
{
	n=read();m=read();ty=read();
	memset(head,-1,sizeof(head));
	for(int i=1;i<=n;i++) p[i]=read();
	for(int i=1;i<n;i++){
		int x=read(),y=read();add(x,y);
	}
	dfs(1,0);calculate(1);
	for(int i=1;i<=m;i++){
		int x=read(),a=read(),y=read(),b=read();
		work(x,a,y,b);
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值