1 条题解
-
0
自动搬运
来自洛谷,原作者为

onlyfiee
running搬运于
2025-08-24 21:14:26,当前版本为作者最后更新于2023-03-14 16:29:12,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
update
修改了笔误。
题意
其实就是带权矩阵的总权。
思路
首先我们来了解这道题的解决方法的思路:
定义 是指 到 的前缀和,不难得到:
$$ sum_{i,j}=a+sum_{i-1,j}+sum_{i,j-1}-sum_{i-1,j-1} $$其中 是指 的值。如果不懂的话可以自己画个图,因为加的时候 重复添加了 ,所以减去。
例如下图,比如我们要求 到 的值:

很容易想到用 减去 的前缀和。
查询
剩下的就是查询了,这个可通过我们之前预处理的 数组来进行查询:
$$ ans=sum_{i,j}+sum_{u-1,v-1}-sum_{u-1,j}-sum_{i,v-1} $$是因为我们 是指 到 ,既然要查询 中的值,根据我们预处理的思想,这个自然不难解决。
tips:一定要自己好好想下,还是比较容易处理的。
细节
解决维护和查询的问题后,这道题目并没有解决因为有这样几句话:
请输出一行一个整数,表示本组数据的所有询问的答案的按位异或和。
也就是求出以 为左上角、 为右下角的矩形元素和对 取余数的结果。
连开 long long 都过不了,要开 unsigned int long long 具体坑点请看代码。
code
#include<bits/stdc++.h> #define int unsigned long long//一定要开 unsigned long long using namespace std; int sum[2050][2050],temp,n,m,q,ans; int u,v,x,y; signed main() { int t; cin>>t; while(t--) { ans=0; //多测不清空,爆零两行泪 cin>>n>>m>>q; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>temp; sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+temp; }//O(nm)预处理 for(int i=1;i<=q;i++) { cin>>u>>v>>x>>y; ans^=sum[x][y]+sum[u-1][v-1]-sum[u-1][y]-sum[x][v-1];// O(1)查询 }//异或处理答案,不取模是因为 unsigned long long 会自然溢出 cout<<ans<<endl; //记得换行 } return 0; }
- 1
信息
- ID
- 8245
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者