[第二场(2)]Automobil

题目描述
Mirko在汽车后座找到了一个N行M列的矩形,矩形第一行由数字1,2,3,…,M,第二行由M+1,M+2,…,2M组成,一直到第N行数字,由(N-1)*M+1, (N-1)M+2,…, NM组成。

举个例子,对于N=3,M=4的矩形,有:

                                1       2       3       4

                                5       6       7       8

                                9       10      11      12

由于这样的矩形不够有趣,于是他进行K次选择,每次选择一行或者一列,将这一行或一列上的所有值乘以一个非负整数。

K次操作完成后,Mirko想知道这个矩形中所有值的总和是多少。由于这个数字可能会非常大,答案将对1e9+7取模。
输入格式
第一行输入三个正整数N(1≤N≤1000000),M(1≤M≤1000000)和K(1≤K≤1000),表示矩形的大小和操作的次数。

接下来K行,每行包含三个字符。如果将第X行的所有值乘以Y,那么输入“R X Y”,如果将第X列的所有值乘以Y,那么输入“S X Y”。
输出格式
输出矩形中所有值的和对1e9+7取模的值。
样例
样例输入1

3 4 4
R 2 4
S 4 1
R 3 2
R 2 0
样例输出1

94
样例输入2

3 1 1
S 1 4
样例输出2

24
样例输入3

2 4 4
S 2 0
S 2 3
R 1 5
S 1 3
样例输出3

80
数据范围与提示
对于第一组样例,完成四次操作后,矩阵情况如下:

                                         1       2       3       4
                                         0       0       0       0
                                         18      20      22      24

这时,矩阵内所有的元素和为:1+2+3+4+0+0+0+0+18+20+22+24=94

解题思路

n,m很大,操作很少,我们考虑从操作入手。
我们先就直接操作行列。
我们会发现,行列的交点,我们的处理是有问题的,比如说第一行2,第一列3,我们仅仅加了5,这少的部分就是x * y - x - y。就按这样处理即可。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdlib>
#include<map>//50000004
#define mod 1000000007
using namespace std;
struct node{
	long long x,y;
	bool operator < (const node &z)const {
		return x < z.x;
	}
}a[1005],a1[1005],d[1005],d1[1005];
int k,len,len1,cnt,cnt1;
char s;
long long ans,n,m;
int main(){
	//freopen("automobil.in","r",stdin);
	//freopen("automobil.out","w",stdout);
	scanf("%lld%lld%d",&n,&m,&k);
	ans = (n * m % mod + 1) % mod * n % mod * m % mod * 500000004 % mod;
	for (int i = 1;i <= k;i ++){
		scanf ("
");
		scanf ("%c",&s);
		int x,y;
		scanf ("%d%d",&x,&y);
		if (s == 'R'){
			a[++ len].x = x;
			a[len].y = y;
		}
		else {
			a1[++len1].x = x;
			a1[len1].y = y;
		}
	}
	sort(a + 1,a + 1 + len);
	sort(a1 + 1,a1 + 1 + len1);
	for (int i = 1;i <= len;i ++){
		if (a[i].x != a[i - 1].x || i == 1)
			d[++ cnt] = a[i];
		else 
			d[cnt].y = d[cnt].y * a[i].y % mod;
	}
	for (int i = 1;i <= len1;i ++){
		if (a1[i].x != a1[i - 1].x || i == 1)
			d1[++ cnt1] = a1[i];
		else 
			d1[cnt1].y = d1[cnt1].y * a1[i].y % mod;
	}
	for (int i = 1;i <= cnt;i ++)
		ans = (ans + ((d[i].x - 1) * m + 1 + d[i].x * m) % mod * m % mod *(d[i].y - 1) % mod * 500000004 % mod) % mod;
	for (int i = 1;i <= cnt1;i ++)
		ans = (ans +(d1[i].x + (n - 1) * m + d1[i].x) % mod * n % mod * (d1[i].y - 1) % mod * 500000004 % mod) % mod; 
	for (int i = 1;i <= cnt;i ++){
		for (int j = 1;j <= cnt1;j ++){
			long long t = (d[i].y * d1[j].y % mod - d[i].y - d1[j].y + mod + 1) % mod;
			ans = (ans + ((d[i].x - 1) * m + d1[j].x) % mod * t % mod + mod)% mod;
		}
	}
	printf("%lld",ans);
}

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