noip 2020 游记

Day \(-\infty\)

随便做做 atcoder 和 codeforces ,作业题还差 8 个,不知道怎么办。

总是有时不时冒出来的模拟赛和组模拟赛的任务,弄得头有点晕,而且我还不是能记得自己写了个 todo list 的人……

Day 0

不想复习,所以不复习。

然而发现自己已经不会 SAM 了,所以去看了看 cmd 的字符串题,然后被打傻了。

晚上看了部电影。

Day 1

七点半起床,八点十五进考场,心态良好。

解压之后在包里看到 testlib ,woc我是不是奶中交互题了? 然而只是一个 spj 。

看 T1 ,这不是拓扑排序裸题?但是为什么要输出分数却不取模啊……

翻到下面, \(d_i\le 5,len\le 10\) ,好像很良心? \(60^{10}\) 刚好没爆?

然后冷静一下发现好像是 \(60^{11}\) ???好,我不冷静了……

多次确认确实会爆 long long ,心态顿时就不好了,开始 xjb 码压位高精并思考高精除法怎么写。

终于写完高精度之后想起来分母一定是 \(60^{11}\) 的约数,那我直接维护分子不就好了??约分只需要除低精就够了???

然后全删了再写一遍,写完还因为大样例太垃圾手动构造了一个爆 long long 的数据确认高精度的正确性。

此时已经过去一个多小时了,心态很不稳。

看 T2 ,发现好像不难,但是不能带 \(\log\)

脑子抽了之后开始猛写双模 hash ,写完并预处理完之后终于想起来好像 exkmp 不太能用 hash 实现。

然后又是删删删,写 exkmp ,幸好一遍过样例。

然后把小数据放到大数据里面,喜提 WA ,于是发现数组没清空。

此时已经过去 2h ,感觉时间不够了。

看 T3 ,发现是个构造题,开搞。

搞……

搞……

搞……

搞不出来。

滚去 T4 ,发现 80pts 不难,40min 迅速想+写完,然后滚回去接着搞 T3 。

搞……

搞……

我裂开了,写个 \(O(n^2m)\) 的大常数做法跑路吧。

写……

没过样例,比赛结束了。

这场比赛打得着实丢人,前两道简单题做了整整 2h ,T3 肝了最久却爆零了,幸好 T4 的 80 分好拿,至少应该能让我参加省选。

被构造题送走了,我在比赛前是万万想不到吧。

感谢去年的运气,让我还不至于现在就回归文化课。如果去年的 CSP 打成今天这个样子,可能这个博客早就停更了吧。

高一的几位打得也一般,但 zz 出乎意料地高(虽然 T1 没写高精度),希望明年省选能翻盘。

Day 1.5

在哪里跌倒,就要在哪里站起来。

水群的时候听到可以分治,又听到可以 \(O(m)\)\(n=2\) (废话),然后就编了个做法。

在值域中间切开,现在只有 0 和 1 的区别。现在考虑两根满的柱子和一根空柱子,我要用 \(O(m)\) 次操作得到一根满的同色柱子和一根满的任意颜色柱子。设给出的柱子分别是 \(x,y,z\) ,且 \(z\) 是空的。

先把 \(y\) 里面的分一半给 \(z\) (注意特判 \(m\) 是奇数的情况,以下同理),然后把 \(x\) 里面的分给 \(y,z\) ,其中 0 往 \(y\) 走,1 往 \(z\) 走,如果目标满了就往另一根走。这样一定可以造出半根同色的柱子,把它丢回给 \(x\) ,然后把另外半根用同样的方法分开 0,1 ,堆到 \(x\) 上。

然后把 \(y\) 丢到 \(z\) 上,把 \(x\) 的两种颜色中的一种丢到 \(y\) 上,把 \(z\) 用同样的方法分开到 \(x,y\) 上即可。

这都没做出来,丢人之至。

代码在随机数据下没有问题,大概操作 \(4.3\times 10^5\) 次。已经通过了洛谷的民间数据。

#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define templ template<typename T>
	#define sz 444
	typedef long long ll;
	typedef double db;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
	templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
	templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
	templ inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
	char __sr[1<<21],__z[20];int __C=-1,__zz=0;
	inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
	inline void print(int x)
	{
		if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
		while(__z[++__zz]=x%10+48,x/=10);
		while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
	}
	void file()
	{
		#ifdef NTFOrz
		freopen("a.in","r",stdin);
		#endif
	}
	inline void chktime()
	{
		#ifdef NTFOrz
		cout<<(clock()-t)/1000.0<<'\n';
		#endif
	}
	#ifdef mod
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
	ll inv(ll x){return ksm(x,mod-2);}
	#else
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
	#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n,m;
int st[sz][sz],tp[sz];
pii ans[888888]; int K;
void mv(int x,int y){assert(tp[x]&&tp[y]!=m);st[y][++tp[y]]=st[x][tp[x]],st[x][tp[x]--]=0;ans[++K]=MP(x,y);}

int lim;
int merge(int x,int y,int z)
{
	int c1=m/2,c2=m-c1;
	rep(i,1,c1) mv(y,z);
	int w=-1;
	drep(i,m,1) { int p=(st[x][i]<=lim?y:z); if (tp[p]==m) p=y+z-p,w=p; mv(x,p); }
	if (w==-1) w=y;
	rep(i,1,(w==y?c2:c1)) mv(y+z-w,x);
	int flg=1; rep(i,1,(w==y?c1:c2)) flg&=(st[w][m-i+1]<=lim)==(st[w][m]<=lim);
	int c=0;
	if (flg) { c=(w==y?c1:c2); if ((st[w][m]<=lim)==(st[x][1]<=lim)) c=0; rep(i,1,(w==y?c1:c2)) mv(w,x); }
	else
	{
		drep(i,m,m-(w==y?c1:c2)+1) if ((st[w][i]<=lim)==(st[x][tp[x]]<=lim)) mv(w,x); else mv(w,y+z-w),++c;
		rep(i,1,c) mv(y+z-w,x);
	}
	drep(i,tp[y],1) mv(y,z); rep(i,1,c) mv(x,y);
	w=-1;
	drep(i,m,1)
	{
		int p;
		if ((st[z][i]<=lim)==(st[x][1]<=lim)) p=x; else p=y;
		if (tp[p]==m) w=p,p=x+y-p; mv(z,p); 
	}
	if (w==-1) w=x;
	return w;
}
void solve(vector<int>V,int l,int r)
{
	if (l==r) return;
	lim=(l+r)>>1; int mid=lim;
	vector<int>V1,V2;
	auto add=[&](int x){if (st[x][1]<=lim) V1.push_back(x);else V2.push_back(x);};
	while (V.size()>1u)
	{
		int x,y;
		x=V.back(),V.pop_back(),y=V.back(),V.pop_back();
		int z=merge(x,y,n+1);
		V.push_back(x+y-z),add(z);
	}
	assert(V.size());add(V[0]);
	solve(V1,l,mid),solve(V2,mid+1,r);
}

int main()
{
	file();
	read(n,m);
	rep(i,1,n) rep(j,1,m) read(st[i][j]); rep(i,1,n) tp[i]=m;
	vector<int>V; drep(i,n,1) V.push_back(i);
	solve(V,1,n);
	rep(i,1,n) rep(j,2,m) assert(st[i][j]==st[i][j-1]);
	assert(K<=820000); cerr<<K<<'\n';
	puts("OK");
//	printf("%d\n",K);
//	rep(i,1,K) printf("%d %d\n",ans[i].fir,ans[i].sec);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章