省选莫逆36

依旧垫底??

看着第二题就顺眼,于是似乎忘记了时间,直接投入3hours++

T1 启程的日子

构造题,发现解一定不大于3

于是3的情况构造是梳子状,就是上下两个交错即可,最后减去一些就好了

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;
}
random_device you;
mt19937 pyt(you());
const int N=505;
int n,m,jz[N][N];char ch[N];
int id[N][N],cid;
int ans[N][N],sum;
struct D{
    int fai[N*N];
    int find(int x){return fai[x]==x?x:fai[x]=find(fai[x]);}
    bool merge(int x,int y){
        int fx=find(x),fy=find(y);
        if(y==x)return false;
        fai[fx]=fy;return true;
    }
    void clear(){fo(i,1,cid)fai[i]=i;}
}d0,d1;
bool jud(int x,int y){
    return x<=n&&x&&y<=m&&y;
}
bool vis[N*N];
vector<pair<int,int>> vec[N*N];
int ji[N*N],cj;
signed main(){
    freopen("bitbit.in","r",stdin);
    freopen("bitbit.out","w",stdout);
    n=read();m=read();
    fo(i,1,n){
        scanf("%s",ch+1);
        fo(j,1,m){
            jz[i][j]=ch[j]-'0',id[i][j]=++cid;
            if(jz[i][j])sum++;
        }
    }
    if(!sum){printf("0");return 0;}
    d1.clear();d0.clear();
    fo(i,1,n)fo(j,1,m)if(jz[i][j]){
        if(jud(i+1,j)&&jz[i+1][j])d1.merge(id[i][j],id[i+1][j]);
        if(jud(i,j+1)&&jz[i][j+1])d1.merge(id[i][j],id[i][j+1]);
    }
    fo(i,1,n)fo(j,1,m)if(!jz[i][j]){
        if(jud(i+1,j)&&!jz[i+1][j])d0.merge(id[i][j],id[i+1][j]);
        if(jud(i,j+1)&&!jz[i][j+1])d0.merge(id[i][j],id[i][j+1]);
    }
    sum=0;
    fo(i,1,n)fo(j,1,m)if(jz[i][j]){
        if(!vis[d1.find(id[i][j])]){
            vis[d1.find(id[i][j])]=true;
            sum++;
            // cerr<<i<<" "<<j<<endl;
        }
    }
    memset(vis,0,sizeof(vis));int sm=0;
    fo(i,1,n)fo(j,1,m)if(!jz[i][j]){
        if(!vis[d0.find(id[i][j])]){
            vis[d0.find(id[i][j])]=true;
            sm++;
            // cerr<<i<<" "<<j<<endl;
        }
    }
    if(n==1||m==1){
        if(sum<=sm+1){
            printf("%d\n",sum);
            fo(i,1,n)fo(j,1,m)if(jz[i][j]&&d1.find(id[i][j])==id[i][j]){
                printf("+\n");
                fo(x,1,n){
                    fo(y,1,m){
                        if(d1.find(id[x][y])==id[i][j])printf("1");
                        else printf("0");
                    }
                    printf("\n");
                }
            }
        }
        else {
            printf("%d\n",sm+1);
            printf("+\n");
            fo(i,1,n){
                fo(j,1,m)printf("1");
                printf("\n");
            }
            fo(i,1,n)fo(j,1,m)if(!jz[i][j]&&d0.find(id[i][j])==id[i][j]){
                printf("-\n");
                fo(x,1,n){
                    fo(y,1,m){
                        if(d0.find(id[x][y])==id[i][j])printf("1");
                        else printf("0");
                    }
                    printf("\n");
                }
            }
        }
        return 0;
    }
    if(sum==1){
        printf("1\n+\n");
        fo(i,1,n){
            fo(j,1,m)printf("%d",jz[i][j]);
            printf("\n");
        }return 0;
    }
    fo(i,1,n)fo(j,1,m)if(!jz[i][j])vec[d0.find(id[i][j])].push_back(make_pair(i,j));
    memset(vis,0,sizeof(vis));
    fo(i,1,cid)if(vec[i].size()){
        int res=0;cj=0;
        for(pair<int,int> j:vec[i]){
            int x=j.first,y=j.second;
            if(jud(x+1,y)&&jz[x+1][y]&&!vis[d1.find(id[x+1][y])]){
                vis[d1.find(id[x+1][y])]=true;res++;ji[++cj]=d1.find(id[x+1][y]);
            }
            if(jud(x-1,y)&&jz[x-1][y]&&!vis[d1.find(id[x-1][y])]){
                vis[d1.find(id[x-1][y])]=true;res++;ji[++cj]=d1.find(id[x-1][y]);
            }
            if(jud(x,y+1)&&jz[x][y+1]&&!vis[d1.find(id[x][y+1])]){
                vis[d1.find(id[x][y+1])]=true;res++;ji[++cj]=d1.find(id[x][y+1]);
            }
            if(jud(x,y-1)&&jz[x][y-1]&&!vis[d1.find(id[x][y-1])]){
                vis[d1.find(id[x][y-1])]=true;res++;ji[++cj]=d1.find(id[x][y-1]);
            }
        }
        // cerr<<i<<" "<<res<<" "<<sum<<endl;
        if(res==sum){
            printf("2\n+\n");
            for(pair<int,int> j:vec[i])jz[j.first][j.second]=1;
            fo(j,1,n){
                fo(k,1,m)printf("%d",jz[j][k]);
                printf("\n");
            }
            printf("-\n");
            fo(j,1,n){
                fo(k,1,m){
                    if(d0.find(id[j][k])==i)printf("1");
                    else printf("0");
                }
                printf("\n");
            }
            return 0;
        }
        fo(j,1,cj)vis[ji[j]]=false;
    }
    fo(i,1,m){
        if(!jz[1][i])ans[1][i]+=1;
        if(!jz[n][i])ans[n][i]+=2;
    }
    fo(j,1,m){
        fo(i,2,n-1){
            if(j&1)ans[i][j]+=1;
            else ans[i][j]+=2;
        }
    }
    printf("3\n");
    printf("+\n");
    if(n==2){
        fo(i,1,n){
            fo(j,1,m){
                if((ans[i][j]&1)||jz[i][j])printf("1");
                else printf("0");
            }
            printf("\n");
        }
        printf("+\n");
        fo(i,1,n){
            fo(j,1,m){
                if((ans[i][j]&2)||jz[i][j])printf("1");
                else printf("0");
            }
            printf("\n");
        }
        printf("-\n");
        fo(i,1,n){
            fo(j,1,m){
                if((ans[i][j]&3)||jz[i][j])printf("1");
                else printf("0");
            }
            printf("\n");
        }
        return 0;
    }
    fo(i,1,n){
        fo(j,1,m){
            if((ans[i][j]&1)||(jz[i][j]&&i!=n))printf("1");
            else printf("0");
        }
        printf("\n");
    }
    printf("+\n");
    fo(i,1,n){
        fo(j,1,m){
            if((ans[i][j]&2)||(jz[i][j]&&i!=1))printf("1");
            else printf("0");
        }
        printf("\n");
    }
    printf("-\n");
    fo(i,1,n){
        fo(j,1,m){
            if((ans[i][j]&3)||(jz[i][j]&&i!=1&&i!=n))printf("1");
            else printf("0");
        }
        printf("\n");
    }
    return 0;
}
``
</details>

# T2 抬头仰望梦的脚步

虽然我搞得很明白,但是我没有时间写了

于是呢,log段等差数列,$\mathcal{O(log)}$从上一个跳过来

就切了

考场上一直在捯饬数字的关系,甚至找到了公差的变化....

<details>
<summary>AC_code</summary>

```cpp
#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 inf=0x3f3f3f3f3f3f3f3f;
int T,n,m,a,b,ans;bool fl;
int gcd(int x,int y){return !y?x:gcd(y,x%y);}
int up(int x,int y){return (x-1)/y+1;}
int V(int n){
    if(n==inf)return inf;
    return (a+n%m*b)%m;
}
int G(int m,int d,int l,int r){
    // cerr<<m<<" "<<d<<" "<<l<<" "<<r<<endl;
    if(l==0)return 0;
    int g=gcd(m,d);
    // cerr<<g<<" "<<((l-1)/g>=r/g)<<endl;
    if((l-1)/g>=r/g)return inf;
    if((l-1)/d<r/d)return (l-1)/d+1;
    if(d>m-d)return G(m,m-d,m-r,m-l);
    int k=G(d,d-m%d,l%d,r%d);
    if(k==inf)return inf;
    l+=k*m;r+=k*m;
    return (l-1)/d+1;
}
int F(int l,int r){
    l=(l-a+m)%m;r=(r-a+m)%m;
    if(l<=r)return G(m,b,l,r);
    return min(G(m,b,l,m-1),G(m,b,0,r));
    // return 0;
}
int W(int val){
    if(val>m-1)return 0;
    int v=0,ret=0;
    v=V(F(0,val));
    if(v<val)ret++;
    // cerr<<"ZZ"<<endl;
    while(v<val){
        // cerr<<v<<" "<<val<<endl;
        int vv=F(v+1,val);
        // cerr<<vv<<endl;
        if(vv==inf)break;
        int d=(V(vv)-v);
        int len=(val-v)/d;
        ret+=len;v+=len*d;
        if(v==val)ret--;
    }
    // cerr<<"SB"<<endl;
    // cerr<<ret<<" "<<val<<endl;
    v=V(F(val,m-1));
    // cerr<<v<<endl;
    if(v!=inf&&v>val)ret++;
    while(v>val&&v!=inf){
        // cerr<<"cao"<<" "<<v<<" "<<val<<endl;
        int vv=F(val,v-1);
        // cerr<<"cao"<<" "<<vv<<endl;
        if(vv==inf)break;
        int d=(v-V(vv));
        int len=(v-val)/d;
        ret+=len;v-=len*d;
        if(v==val)ret--;
    }
    // cerr<<"ZZ"<<endl;
    return ret;
}
signed main(){
    freopen("fuwafuwa.in","r",stdin);
    freopen("fuwafuwa.out","w",stdout);
    T=read();
    while(T--){
        a=read();b=read();m=read();n=read();
        a%=m;b%=m;n--;a=(a+b)%m;
        int g=gcd(b,m);int ret=0;
        ans=n/(m/g);ret=W(V(n));
        if(ans)ret=max(ret,W(V(n)+g));
        printf("%lld\n",ans+ret);
    }
    return 0;
}
``
</details>

# T3  小孩召开法

似乎是EGF,不会不会
posted @ 2022-03-23 21:54  fengwu2005  阅读(35)  评论(0编辑  收藏  举报