[第二場(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 ("\n");
		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);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章