CSP-S 2019 游记

CSP-S 2019 游记

Day1

t3调不完导致心态爆炸,所以咕咕咕
就贴一个赛后重写的能过luogu自测的代码吧...

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define debug(x) cerr<<#x<<" = "<<x
#define sp <<"  "
#define el <<endl
#define fgx cerr<<" ---------------------------------------------- "<<endl
#define uint unsigned int 
#define ULL unsigned long long
#define DB double
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
inline LL read(){
	LL nm=0; bool fh=true; char cw=getchar();
	for(;!isdigit(cw);cw=getchar()) fh^=(cw=='-');
	for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
	return fh?nm:-nm;
}
#define M 2020
int n,c[M][M],sz[M],pre[M][M],nxt[M][M],fs[M],las[M],f[M][M],hv[M][M],id[M][M];
inline int fd(int x,int w){return f[x][w]==w?w:f[x][w]=fd(x,f[x][w]);}
int Pos[M],p[M],pos,q[M],hd,tl,from[M],fa[M];
int perm[M];
inline void deliver(int x){
	hd=tl=1,pos=n+1;
	if(fs[x]) q[tl]=c[x][fs[x]],from[tl++]=x;
	else{
		for(int i=1;i<=sz[x];i++) if(pre[x][i]==0&&(fd(x,i)!=fd(x,las[x])||hv[x][fd(x,las[x])]==sz[x]))
			q[tl]=c[x][i],from[tl++]=x;
	}
	while(hd<tl){
		int y=q[hd]; fa[y]=from[hd],++hd;
		int k=id[y][fa[y]];
		if((las[y]==0||las[y]==k)&&nxt[y][k]==0&&(fd(y,k)!=fd(y,fs[y])||hv[y][fd(y,fs[y])]==sz[y])) pos=min(pos,y);
		if(nxt[y][k]>0){q[tl]=c[y][nxt[y][k]],from[tl++]=y;continue;} if(las[y]==k) continue;
		for(int i=1;i<=sz[y];i++) if(fd(y,i)!=fd(y,k)&&pre[y][i]==0&&i!=fs[y]){
			if(fd(y,k)==fd(y,las[y])) continue; if(fd(y,i)==fd(y,fs[y])) continue;
			if(fd(y,k)==fd(y,fs[y])&&fd(y,i)==fd(y,las[y])&&hv[y][fd(y,k)]+hv[y][fd(y,i)]<sz[y]) continue;
			q[tl]=c[y][i],from[tl++]=y;
		}
	}
	printf("%d ",pos);
	assert(pos<=n);
	las[pos]=id[pos][fa[pos]]; int y=fa[pos];
	for(;y!=x;y=fa[y],pos=fa[pos]){
		int come=id[y][fa[y]];
		int leave=id[y][pos];
		nxt[y][come]=leave;
		pre[y][leave]=come;
		int a=fd(y,come);
		int b=fd(y,leave);
		if(a==b) continue;
		hv[y][b]+=hv[y][a];
		f[y][a]=b;
	} fs[x]=id[x][pos];
}
inline void solve(){
	n=read();
	for(int i=1;i<=n;i++) perm[i]=i,swap(perm[i],perm[rand()%i+1]);
	for(int x=1;x<=n;fs[x]=las[x]=sz[x]=0,x++) while(sz[x])
		pre[x][sz[x]]=nxt[x][sz[x]]=c[x][sz[x]]=f[x][sz[x]]=hv[x][sz[x]]=0,--sz[x];
	for(int i=1;i<=n;i++) Pos[i]=read();
	for(int i=1,x,y;i<n;++i){
		x=read(),y=read();
		id[x][y]=++sz[x],id[y][x]=++sz[y];
		c[x][sz[x]]=y,c[y][sz[y]]=x;
		hv[x][sz[x]]=hv[y][sz[y]]=1;
		f[x][sz[x]]=sz[x];
		f[y][sz[y]]=sz[y];
	}
	for(int x=1;x<=n;x++) if(sz[x]==1) las[x]=fs[x]=1;
	if(n==1){puts("1");return;}
	for(int x=1;x<=n;x++) deliver(Pos[x]); puts("");//puts("good");
}
int main(){
	// freopen("tree.in","r",stdin);
	// freopen("tree.out","w",stdout);
	for(int Cas=read();Cas;--Cas) solve();
	return 0;
}

Day2

t1想了一会发现随便搞一下DP
DP是个生成函数卷积形式,有没有人分治NTT的啊
t2大概猜了个结论,发现他过了所有的样例
t3觉得随便DP一下,后来越想与不对劲,画了画图,大概对于每个点统计一下删除能使得他能变成重心的边的数量即可,分三类分别求,疯狂码码码结束之后还有半小时

人生中第一次也是最后一次正式的CSP就这样结束了


upd:代码发下来,自测并没有挂太多分,总算是有惊无险。。。。

posted @ 2019-11-18 12:27  OYJason  阅读(484)  评论(0编辑  收藏  举报