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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章