省选莫逆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,不会不会
QQ:2953174821