luogu[U103720]薇尔莉特 题解

题面点这里
概括一下题目,就是维护矩阵or,要求最后整个矩阵的和,异或和
考虑对需要操作的值 v a l val val进行二进制拆分,由于or对于一个二进制位上的操作是永久性的,那我们对每一位进行二维差分,最后做一遍二维前缀和,对大于 1 1 1的都当做 1 1 1看,就结束了

#include<bits/stdc++.h>
#define C getchar()
#define Mod 1000000007
#define LL long long
#define rt register int
using namespace std;
inline int read() {
	int num = 0;
	char c = C;
	for(;c<'0' || c>'9';c=C);
	for(;c>='0' && c<='9';c=C) num = (num << 1) + (num << 3) + (c ^ 48);
	return num;
}

int b[510][510][32],p[40];
LL a[510][510];

int main() {
	
	int n = read() , m = read() , T = read();
	LL Ans2 = read();
	
	int Max = 0;
	while (T --) {
		int l = read() , r = read() , x = read() , y = read() , v = read();
		int tmp = -1;
		while (v) {
			p[++ tmp] = v & 1;
			v >>= 1;
		}
		Max = max(Max , tmp);
		for(rt i=0;i<=tmp;++i) {
			if (p[i] == 0) continue;		
			++ b[l][r][i] , -- b[l][y + 1][i] , -- b[x + 1][r][i] , ++ b[x + 1][y + 1][i];
		}
	}
	
	for(rt k=0;k<=Max;++k) {
		for(rt i=1;i<=n;++i) {
			for(rt j=1;j<=m;++j) b[i][j][k] += b[i - 1][j][k] + b[i][j - 1][k] - b[i - 1][j - 1][k];
		}
	}
	
	for(rt k=0;k<=Max;++k) {
		for(rt i=1;i<=n;++i) {
			for(rt j=1;j<=m;++j) if (b[i][j][k]) a[i][j] |= (LL)1 << k;
		}
	}
	
	LL Ans1 = 0;
	for(rt i=1;i<=n;++i) for(rt j=1;j<=m;++j) Ans1 += a[i][j] , Ans1 %= Mod , Ans2 ^= a[i][j];
	Ans1 %= Mod;
	
	printf("%lld %lld %lld\n",Ans1,Ans2,Ans1 * Ans2 % Mod);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值