题解
因为觉得这是一道出的很好的模拟题,所以拿过来了。
上文中提到的flip操作其实就是取反。
暴力做法是$O(nq)$的,挂。
看数据,考虑有没有什么接近线性的做法:我们将整个结果展开。
比如这么一个方阵:
他的unusual square 就是由于是在模$2$的环境下进行,这个式子后半部分都是没有用的东西。所以只要时时刻刻维护前面平方项的和即可。
然而…每一次操作都必然改变一项且仅改变一个平方项,使之从0变1或从1变0.
所以做法就是
- 读入时不保留矩阵,只算平方项
- 更新时只要知道它更新了即可,然后把平方和异或1。
这个算法的复杂度就是$O(n^2+q)-O(1)$的。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using namespace std;
typedef long long ll;
int n,sum=0,lg[1005],q,jc;
//保留对角线只是我无聊...
int read(){
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return f*x;
}
void init(){
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&((i==j)?lg[i]:jc));
for(int i=0;i<n;i++)
sum^=lg[i];
}
void solve(){
scanf("%d",&q);
int op;
for(int i=0;i<q;i++){
scanf("%d",&op);
if(op==3)printf("%d",sum);
else scanf("%d",&jc),sum^=1;
}
}
int main(){
init();
solve();
return 0;
}