题解 数学题
我就静静的看着出题人用一个我不会的东西解释另一个我不会的东西
首先可以 bitset 卡常+线性基模拟得到 50 pts
然后重点来优化如何快速判断一个数的每一位被翻转后能否插入没有这个数的线性基
对这是个不需要删除操作的做法
先建出原序列的线性基,记录每个线性基内的数异或过谁以及线性基外的数能被哪些基底构成
然后对于第 行,问题等价于问 能否插入删去 的线性基
若 不在线性基中则判断 能否插入即可,可以高斯消元预处理
若 在线性基中再分类讨论
若 作为基底构成过别的数删了等于没删
否则若 能被表示需要考虑它是不是被 表示出来的,查 的组成即可
复杂度
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
//#define int long long
int n, m;
char mp[1010][1010];
namespace force{
int base[N], tem[1010][1010];
int insert(int t) {
for (int i=1; i<=m; ++i) if (tem[t][i]) {
if (!base[i]) {base[i]=t; return 1;}
else {
for (int j=1; j<=m; ++j) tem[t][j]^=tem[base[i]][j];
}
}
return 0;
}
int query() {
int cnt=0;
for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) tem[i][j]=mp[i][j];
for (int i=1; i<=m; ++i) base[i]=0;
for (int i=1; i<=n; ++i) cnt+=insert(i);
return cnt;
}
void solve() {
int lim=query();
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
mp[i][j]^=1;
int t=query();
if (t<lim) printf("-");
else if (t>lim) printf("+");
else printf("0");
mp[i][j]^=1;
}
printf("\n");
}
}
}
namespace task1{
int base[N], bkp_base[N], cnt, bkp_cnt;
bitset<1010> mp2[1010], tem[1010], bkp_tem[1010];
void clear() {
cnt=0;
for (int i=1; i<=n; ++i) tem[i]=mp2[i];
for (int i=1; i<=m; ++i) base[i]=0;
}
void save() {
bkp_cnt=cnt;
for (int i=1; i<=n; ++i) bkp_tem[i]=tem[i];
for (int i=1; i<=m; ++i) bkp_base[i]=base[i];
}
void recover() {
cnt=bkp_cnt;
for (int i=1; i<=n; ++i) tem[i]=bkp_tem[i];
for (int i=1; i<=m; ++i) base[i]=bkp_base[i];
}
void insert(int t) {
for (int i=tem[t]._Find_first(); i<1010; i=tem[t]._Find_next(i)) {
if (!base[i]) {base[i]=t, ++cnt; return ;}
else tem[t]^=tem[base[i]];
}
}
int query() {
clear();
for (int i=1; i<=n; ++i) insert(i);
return cnt;
}
void solve() {
for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) mp2[i][j]=(mp[i][j]==1);
int lim=query();
for (int i=1; i<=n; ++i) {
clear();
for (int j=1; j<=n; ++j) if (i!=j) insert(j);
save();
for (int j=1; j<=m; ++j) {
recover();
tem[i].flip(j);
insert(i);
if (cnt<lim) printf("-");
else if (cnt>lim) printf("+");
else printf("0");
}
printf("\n");
}
}
}
namespace task{
int basis[N], siz;
bool in_basis[N], able[N];
bitset<1010> tem[1010], form[1010];
struct matrix{
bool isable[1010];
bitset<1010> a[1010], form[1010];
inline bitset<1010>& operator[] (int t) {return a[t];}
void put() {
cout<<"---mat---"<<endl;
for (int i=1; i<=m; ++i) {for (int j=1; j<=m; ++j) cout<<a[i][j]; cout<<endl;}
cout<<"---form---"<<endl;
for (int i=1; i<=m; ++i) {for (int j=1; j<=m; ++j) cout<<form[i][j]; cout<<endl;}
}
void gauss() {
for (int i=1; i<=m; ++i) {
for (int j=i; j<=m; ++j)
if (a[j][i]) {swap(a[i], a[j]); swap(form[i], form[j]); break;}
else if (!a[i].none() && a[j].none()) swap(a[i], a[j]), swap(form[i], form[j]);
if (!a[i][i]) continue;
for (int j=1; j<=m; ++j) if (i!=j && a[j][i]) a[j]^=a[i], form[j]^=form[i];
}
for (int i=1; i<=m; ++i) if (a[i][i] && a[i].count()==1) isable[i]=1;
}
bool able(int i) {return isable[i];}
}mat;
void insert(int t) {
form[t][t]=1;
for (int i=tem[t]._Find_first(); i<1010; i=tem[t]._Find_next(i)) {
if (!basis[i]) {basis[i]=t; in_basis[t]=1; ++siz; return ;}
else tem[t]^=tem[basis[i]], form[t]^=form[basis[i]];
}
for (int i=form[t]._Find_first(); i<1010; i=form[t]._Find_next(i)) able[i]=1;
}
void solve() {
for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) tem[i][j]=(mp[i][j]==1);
for (int i=1; i<=n; ++i) insert(i);
for (int i=1; i<=m; ++i) if (basis[i]) mat[i]=tem[basis[i]], mat.form[i]=form[basis[i]]; //, cout<<tem[basis[i]]<<endl;
mat.gauss(); //mat.put();
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
if (!in_basis[i]) printf("%c", mat.able(j)?'0':'+');
else {
if (able[i]) printf("%c", mat.able(j)?'0':'+');
else {
if (!mat.able(j)) printf("0");
else printf("%c", mat.form[j][i]?'-':'0');
}
}
}
printf("\n");
}
}
}
signed main()
{
freopen("math.in", "r", stdin);
freopen("math.out", "w", stdout);
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) {
scanf("%s", mp[i]+1);
for (int j=1; j<=m; ++j) mp[i][j]^=48;
}
// force::solve();
// task1::solve();
task::solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!