CSP-S 2019 游记

拟墨画扇 提交于 2019-12-04 20:16:40

CSP-S 2019 游记

Day1

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

#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:代码发下来,自测并没有挂太多分,总算是有惊无险。。。。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!