[D2T1]u

题目描述

考虑一个 n ∗ n 的矩阵 A,初始所有元素均为 0。

执行 q 次如下形式的操作:给定 4 个整数 r, c, l, s,对于每个满足 x ∈ [r, r+l), y ∈ [c, x-r+c] 的元素 (x, y),将权值增加 s。也就是,给一个左上顶点为 (r, c)、直角边长为 l 的下三角区域加上 s。

输出最终矩阵的元素异或和。

输入格式

第一行两个整数 n, q。

接下来 q 行,每行四个整数 r, c, l, s,代表一次操作。

输出格式

输出一行,一个整数,代表答案。

样例

样例输入
10 4
1 1 10 1
5 5 4 4
1 9 4 3
3 3 5 2
样例输出
0
样例解释
1 0 0 0 0 0 0 0 3 0
1 1 0 0 0 0 0 0 3 3
1 1 3 0 0 0 0 0 3 3
1 1 3 3 0 0 0 0 3 3
1 1 3 3 7 0 0 0 0 0
1 1 3 3 7 7 0 0 0 0
1 1 3 3 7 7 7 0 0 0
1 1 1 1 5 5 5 5 0 0
1 1 1 1 1 1 1 1 1 0
1 1 1 1 1 1 1 1 1 1

数据范围与提示

对于100%的数据,保证 n ∈ [1, 103],q ∈ [0, 3 ∗ 105],r, c, l ∈ [1, n],s ∈ [1, 109]。

题解

自己真的太菜,看来可能真不适合,真要离开了。
不同于其他方法,此题本人没用差分,用了一个复杂度更高的为nq的算法。
在每个三角形斜边的点标记添加的值,r + l那一行标记一个负值。
从上到下遍历,一直加,便可以得到矩阵想要的值,没啥好说的,如有不明白的看下代码绝对就懂了。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<ctime>
#define mp(a,b) make_pair(a,b)
#define fi first
#define se second
#define LL long long
using namespace std;
int n,q;
long long ans,flag[1005][1005];
int main(){
	scanf ("%d%d",&n,&q);
	while (q --){
		int r,c,l,s;
		scanf ("%d%d%d%d",&r,&c,&l,&s);
		int maxn = min(r + l,n + 1);
		for (int i = 0;i < l && r + i <= n && c + i <= n;i ++){
			flag[r + i][c + i] += s;
			flag[maxn][c + i] -= s;
		}
	}
	for (int j = 1;j <= n;j ++){
		long long now = 0;
		for (int i = 1;i <= n;i ++){
			now += flag[i][j];
			ans = ans ^ now;
		}
	}
	printf("%lld
",ans);
}

3e8,跑过了1s,大概是因为没有跑满,毕竟那种数据太不正常了。
欢迎各位大佬爆踩

原文地址:https://www.cnblogs.com/lover-fucker/p/13567578.html