省选魔你32

好吧好吧,我又垫底了...

今天抱着要先打完暴力的想法干完了T1,此时30分钟,其实本来想20min打完所有暴力的...

然后T2我认为第一档部分分是最简单的,于是可以预料我完蛋了

T3找到了一个反色原理,然后想用啥玩意维护一下,于是又死了......

T1 梦批糼

我是\(\mathcal{O(n^6)}\)草过去的

AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=65;
const int mod=998244353;
int ksm(int x,int y){
    int ret=1;
    while(y){
        if(y&1)ret=ret*x%mod;
        x=x*x%mod;y>>=1;
    }return ret;
}
int n,m,k,w,ans,cnt;
int jz[N][N][N],il[N][N][N],ie[N][N][N],cf[N][N][N];
signed main(){
    freopen("dream.in","r",stdin);
    freopen("dream.out","w",stdout);
    n=read();m=read();k=read();w=read();
    fo(i,1,n)fo(j,1,m)fo(o,1,k)il[i][j][o]=ie[i][j][o]=read();
    fo(i,1,n)fo(j,1,m)fo(o,1,k)jz[i][j][o]=read();
    fo(i,1,n)fo(j,1,m)fo(o,1,k)il[i][j][o]+=il[i][j][o-1];
    fo(i,1,n)fo(j,1,m)fo(o,1,k)il[i][j][o]+=il[i][j-1][o];
    fo(i,1,n)fo(j,1,m)fo(o,1,k)il[i][j][o]+=il[i-1][j][o];
    if(!w){printf("0");return 0;}
    fo(li,1,n)fo(ri,li,n)fo(lj,1,m)fo(rj,lj,m)fo(lo,1,k)fo(ro,lo,k){
        int fi=il[ri][rj][ro]-il[ri][rj][lo-1]-il[ri][lj-1][ro]-il[li-1][rj][ro]+il[ri][lj-1][lo-1]+il[li-1][rj][lo-1]+il[li-1][lj-1][ro]-il[li-1][lj-1][lo-1];
        if(fi!=(ri-li+1)*(rj-lj+1)*(ro-lo+1))break;
        cnt++;cf[li][lj][lo]++;
        cf[li][lj][ro+1]--;cf[li][rj+1][lo]--;cf[ri+1][lj][lo]--;
        cf[li][rj+1][ro+1]++;cf[ri+1][lj][ro+1]++;cf[ri+1][rj+1][lo]++;
        cf[ri+1][rj+1][ro+1]--;
    }
    fo(i,1,n)fo(j,1,m)fo(o,1,k)cf[i][j][o]+=cf[i][j][o-1];
    fo(i,1,n)fo(j,1,m)fo(o,1,k)cf[i][j][o]+=cf[i][j-1][o];
    fo(i,1,n)fo(j,1,m)fo(o,1,k)cf[i][j][o]+=cf[i-1][j][o];
    int cmt=ksm(8,mod-2)*n*(n+1)%mod*m*(m+1)%mod*k*(k+1)%mod;
    cmt=ksm(cmt,mod-2);
    fo(i,1,n)fo(j,1,m)fo(o,1,k)if(ie[i][j][o]){
        // cerr<<i<<" "<<j<<" "<<o<<" "<<cf[i][j][o]<<" "<<cnt<<" "<<cmt<<" "<<(1-ksm(9,mod-2)%mod+mod)<<endl;
        ans=(ans+jz[i][j][o]*(ksm(cnt*cmt%mod,w)-ksm((cnt-cf[i][j][o])*cmt%mod,w)+mod)%mod)%mod;
    }
    printf("%lld",ans);
    return 0;
}

T2 等你哈苏德

网络流...据说他们的方法比我的快不知道多少??!!他们是先给不定向的边定向然后推流

我直接跑欧拉回路,注意奇度数的点要向后一个连边,不能直接向下一个奇度数连边,这样有可能会错

AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=3e4+5;
const int inf=0x3f3f3f3f;
struct NET{
    struct E{int to,nxt,val;}e[N*200];
    int head[N*10],hea[N*10],rp=1,s=1,t=2;
    void add_edg(int x,int y,int z){
        e[++rp].to=y;e[rp].nxt=head[x];
        e[rp].val=z;head[x]=rp;
    }
    void add(int x,int y,int z){
        add_edg(x,y,z);
        add_edg(y,x,0);
    }
    int dis[N*10],seg=2;
    bool bfs(){
        memset(dis,0x3f,sizeof(dis));
        memcpy(head,hea,sizeof(hea));
        queue<int> q;while(!q.empty())q.pop();
        q.push(s);dis[s]=0;
        while(!q.empty()){
            int x=q.front();q.pop();
            for(int i=head[x];i;i=e[i].nxt){
                int y=e[i].to;
                if(!e[i].val||dis[y]<=dis[x]+1)continue;
                dis[y]=dis[x]+1;q.push(y);
                if(y==t)return true;
            }
        }
        return false;
    }
    int dfs(int x,int in){
        if(x==t)return in;
        int rest=in,go=0;
        for(int i=head[x];i;head[x]=i=e[i].nxt){
            int y=e[i].to;
            if(!e[i].val||dis[y]!=dis[x]+1)continue;
            go=dfs(y,min(e[i].val,rest));
            if(go)rest-=go,e[i].val-=go,e[i^1].val+=go;
            else dis[y]=0;
            if(!rest)break;
        }
        return in-rest;
    }
    int dinic(){
        int ret=0;
        memcpy(hea,head,sizeof(head));
        while(bfs())ret+=dfs(s,inf);
        return ret;
    }
}net;
int n,m,mm;
struct QJ{int l,r,c;}qj[N*2];
int lsh[N*2],lh;
int id[N*2][2],im[N*2][2],du[N*2];
int odd[N*2],cod,ji[N*2];
signed main(){
    freopen("wait.in","r",stdin);
    freopen("wait.out","w",stdout);
    mm=m=read();n=read()+1;
    fo(i,1,m){
        qj[i].l=read();qj[i].r=read()+1;qj[i].c=read();
        lsh[++lh]=qj[i].l;lsh[++lh]=qj[i].r;
    }
    sort(lsh+1,lsh+lh+1);lh=unique(lsh+1,lsh+lh+1)-lsh-1;
    fo(i,1,m){
        qj[i].l=lower_bound(lsh+1,lsh+lh+1,qj[i].l)-lsh;
        qj[i].r=lower_bound(lsh+1,lsh+lh+1,qj[i].r)-lsh;
        du[qj[i].l]++;du[qj[i].r]++;
    }
    fo(i,1,lh)if(du[i]&1){
        qj[++m].l=i;qj[m].r=i+1;qj[m].c=-1;
        du[i]++;du[i+1]++;
    }
    fo(i,1,lh){
        id[i][0]=++net.seg;id[i][1]=++net.seg;
        net.add(net.s,id[i][0],du[i]>>1);
        net.add(id[i][1],net.t,du[i]>>1);
    }
    fo(i,1,m){
        im[i][0]=++net.seg;im[i][1]=++net.seg;
        net.add(im[i][0],im[i][1],1);
        net.add(id[qj[i].l][0],im[i][0],(qj[i].c==-1||qj[i].c==0));
        if(i<=mm){ji[i]=net.rp;}
        net.add(im[i][1],id[qj[i].r][1],(qj[i].c==-1||qj[i].c==0));
        net.add(id[qj[i].r][0],im[i][0],(qj[i].c==-1||qj[i].c==1));
        net.add(im[i][1],id[qj[i].l][1],(qj[i].c==-1||qj[i].c==1));
    }
    int res=net.dinic();
    if(res!=m){printf("-1");return 0;}
    fo(i,1,mm)printf("%d ",net.e[ji[i]].val^1);
}

T3 喜欢最最痛

不会,lct维护动态dp

posted @ 2022-03-15 19:33  fengwu2005  阅读(53)  评论(1编辑  收藏  举报