CF1864D 题解
CF1864D Matrix Cascade 题解
Links
Description
给定一个
定义一次操作为:选择矩阵上第
其中,“取反”的意思为:把
求要把给定矩阵全变为
有
数据范围:
Solution
观察题目的操作,我们可以很容易的发现每次操作改变的是下面的一个等腰直角三角形(当然会因为矩阵有边界被截掉一部分)。
观察这个区域左边的那条线,发现它的表达式为
如果我们对于每个点直接暴力修改得到的是
按照顺序枚举后,我们就不需要考虑左边界了,让我们来看一下右侧的边界,根据题目条件很容易得到满足的条件是是
需要注意的是,树状数组无法支持负下标,因此我们将所有的
Codes
#include <bits/stdc++.h> using namespace std; #define int long long void read(int &p) { p = 0; int k = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') { k = -1; } c = getchar(); } while (c >= '0' && c <= '9') { p = p * 10 + c - '0'; c = getchar(); } p *= k; return; } void write_(int x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) { write_(x / 10); } putchar(x % 10 + '0'); } void writesp(int x) { write_(x); putchar(' '); } void writeln(int x) { write_(x); putchar('\n'); } int T; int n; char mp[5100][5100]; int tree[10011]; inline int lowbit(const int &i) { return (-i)&(i); } inline void update(int x) { for(;x <= 2 * n;x+= lowbit(x)) { tree[x]++; } } inline int query(int x) { int res = 0; for(;x;x -= lowbit(x)) { res += tree[x]; } return res; } int ans; void solution() { ans = 0; read(n); for(int i = 1;i <= 2 * n;i++) { tree[i] = 0; } for(int i = 1;i <= n;i++) { scanf("%s",mp[i] + 1); } for(int sum = 2;sum <= 2 * n;++sum) { for(int i = max(1LL,sum - n),j = min(n,sum - 1);i < sum && i <= n;i++,j--) { if(((mp[i][j] - '0') + query(i - j + n)) & 1) { ++ans; update(i - j + n); } } } writeln(ans); } signed main() { read(T); while(T--) { solution(); } return 0; }
本文来自博客园,作者:cn_ryh,转载请注明原文链接:https://www.cnblogs.com/yuhang-ren/p/17671133.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步