結果
| 問題 |
No.1141 田グリッド
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-08-01 11:42:48 |
| 言語 | C++17(clang) (17.0.6 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 195 ms / 2,000 ms |
| コード長 | 3,957 bytes |
| コンパイル時間 | 2,644 ms |
| コンパイル使用メモリ | 122,624 KB |
| 実行使用メモリ | 16,896 KB |
| 最終ジャッジ日時 | 2024-07-07 21:09:09 |
| 合計ジャッジ時間 | 7,754 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 31 |
ソースコード
#include <iostream>
#include <vector>
using namespace std;
using int64 = long long;
const int MOD = 1000000007;
struct mint {
int64 x;
mint(const int64 x1=0) { x = x1%MOD; };
mint& operator++(int n) { x+=1; return *this; };
mint& operator--(int n) { x-=1; return *this; };
mint& operator=(int64 n) { x=n%MOD; return *this; };
mint& operator--() {x-=1; return *this; };
mint& operator+=(const mint a) { if ( (x+=a.x) >= MOD) x-=MOD; return *this; }
mint& operator-=(const mint a) { if ( (x+= MOD-a.x) >= MOD) x-= MOD; return *this; }
mint& operator*=(const mint a) { (x*=a.x) %= MOD; return *this; }
mint& operator/=(const mint a) { return (*this) *= a.inv();}
mint operator+(const mint a) const { mint res(*this); return res+=a; }
mint operator-(const mint a) const { mint res(*this); return res-=a; }
mint operator*(const mint a) const { mint res(*this); return res*=a; }
mint operator/(const mint a) const { mint res(*this); return res/=a; }
mint inv() const { return pow(MOD-2);}
friend ostream& operator<<(ostream &os, const mint a) noexcept { return os << a.x; }
constexpr bool operator == (const mint& r) const noexcept { return this->x == r.x; }
constexpr bool operator != (const mint& r) const noexcept { return this->x != r.x; }
mint pow(long long t) const {
if (!t) return mint(1);
mint a = pow(t>>1);
a*=a;
if(t&1) a*= *this;
return a;
}
};
long long pow(long long a, long long n, long long p) {
long long res = 1;
while(n!=0) {
if (n%2) {
res *= a;
res %= p;
}
a *= a;
a %= p;
n >>= 1;
}
return res % p;
}
long long inv(long long a) {
return pow(a, MOD-2, MOD);
}
int main() {
int h,w;
cin >> h >> w;
vector<vector<long long>> a(h, vector<long long>(w,0));
for (int i=0; i<h; i++) {
for (int j=0; j<w; j++) {
cin >> a[i][j];
}
}
vector<vector<long long>> lupro(h+1, vector<long long>(w+1, 1));
for (int i=1; i<=h; i++) {
for (int j=1; j<=w; j++) {
lupro[i][j] = (lupro[i-1][j] * lupro[i][j-1])%MOD;
(lupro[i][j] *= inv(lupro[i-1][j-1])) %= MOD;
(lupro[i][j] *= a[i-1][j-1]) %= MOD;
}
}
vector<vector<long long>> rupro(h+1, vector<long long>(w+1, 1));
for (int i=1; i<=h; i++) {
for (int j=w-1; j>=0; j--) {
rupro[i][j] = (rupro[i-1][j] * rupro[i][j+1])%MOD;
(rupro[i][j] *= inv(rupro[i-1][j+1])) %= MOD;
(rupro[i][j] *= a[i-1][j]) %= MOD;
}
}
vector<vector<long long>> ldpro(h+1, vector<long long>(w+1, 1));
for (int i=h-1; i>=0; i--) {
for (int j=1; j<=w; j++) {
ldpro[i][j] = (ldpro[i+1][j] * ldpro[i][j-1])%MOD;
(ldpro[i][j] *= inv(ldpro[i+1][j-1])) %= MOD;
(ldpro[i][j] *= a[i][j-1]) %= MOD;
}
}
vector<vector<long long>> rdpro(h+1, vector<long long>(w+1, 1));
for (int i=h-1; i>=0; i--) {
for (int j=w-1; j>=0; j--) {
rdpro[i][j] = (rdpro[i+1][j] * rdpro[i][j+1])%MOD;
(rdpro[i][j] *= inv(rdpro[i+1][j+1])) %= MOD;
(rdpro[i][j] *= a[i][j]) %= MOD;
}
}
int q;
cin >> q;
for (int i=0; i<q; i++) {
int r,c;
cin >> r >> c;
mint ans = 1;
ans *= lupro[r-1][c-1]; // 左上
ans *= rupro[r-1][c]; // 右上
ans *= ldpro[r][c-1]; // 左下
ans *= rdpro[r][c]; // 右下
cout << ans << endl;
}
}
/*
*
* 1 2 3
* 4 0 6
* 7 8 9
*
* 000001 000001 000001 000001
* 000001 000001 000002 000006
* 000001 000004 000040 000720
* 000001 000028 002240 362880
* 5*6*8*9 = 2160
* (3612880 / 6) / 28 = 2160
*
* 累積積
* 01 02 03 04
* 05 06 07 08
* 09 10 11 12
* 13 14 15 16
*
* x^p ≡ x
* x^{p-1} ≡ 1 mod p
* x^{p-2} ≡ 1/x mod p
*
*/