2022ICPC沈阳站 Problem F. Half Mixed
构造题。
题意:给定n,m,求一个nm的0/1矩阵,满足纯子矩阵数==杂子矩阵数。(纯子矩阵为内部只含有0或1的子矩阵,杂子矩阵反之)
其中 n,m<=1e6,nm<=5e6.
显然杂子矩阵不好处理,那我们计算纯子矩阵。我们可以将矩阵划分为一列0一列1的形式,保证纯子矩阵能够简单的得到,我们的总的子矩阵个数为(n+1) * n/2 * (m+1) * m/2(被2整除,否则无解),而当交错赋值时,纯子矩阵个数为(n+1) * n/2 * m,当然若m为奇数,swap(n , m)。我们观察再发现,相同的两列会产生多(n+1) * n/2,相同地k列会多产生 (k-1) * k/2 *(n+1) * n/2个纯子矩阵,故我们可以使得前k1个列均为0,接下来k2列为1,,,直至产生地多的纯子矩阵个数==(m+1) * m/4 - m,每次贪心地减少尽可能多的,易知必定有解。
代码:
#define int long long
using namespace std;
template <typename T> void read(T &t) {
t=0; char ch=getchar(); int f=1;
while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
do { (t*=10)+=ch-'0'; ch=getchar(); } while ('0'<=ch&&ch<='9'); t*=f;
}
template <typename T> void write(T t) {
if (t<0) { putchar('-'); write(-t); return; }
if (t>9) write(t/10);
putchar('0'+t%10);
}
int cnt[1000100],tot,a[2000100];
int g[7001000];
void solve(){
int ok=0;
tot=0;
int n,m;read(n),read(m);
int w=n*(n+1)/2*m*(m+1)/2;
if(w%2){
puts("No");
return;
}
if(m*(m+1)/2%2) swap(n,m),ok=1;
int now=m*(m-3)/4;
while(now){
int p=lower_bound(a+2,a+1000010,now)-a;
while(a[p]>now) p--;
now-=a[p];
cnt[++tot]=p;
}
int q=0,pre=1;
for(int i=1;i<=tot;i++){
q^=1;
for(int j=pre;j<=pre+cnt[i]-1;j++){
for(int k=1;k<=n;k++){
g[k+j*(n+1)]=q;
}
}
pre=pre+cnt[i];
}
for(int i=pre;i<=m;i++){
q^=1;
for(int j=1;j<=n;j++){
g[j+(n+1)*i]=q;
}
}
puts("Yes");
if(!ok){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
write(g[i+j*(n+1)]);printf(" ");
}
cout<<endl;
}
}
else{
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
write(g[j+i*(n+1)]);
printf(" ");
}
puts("");
}
}
}
signed main(){
int T;read(T);
for(int i=2;i<=1000010;i++){
a[i]=(i-1)*i/2;
}
while(T--) solve();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】