結果

問題 No.1141 田グリッド
ユーザー Ricky_ponRicky_pon
提出日時 2020-07-31 22:04:17
言語 C++17
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 1,021 ms / 2,000 ms
コード長 7,091 bytes
コンパイル時間 2,309 ms
コンパイル使用メモリ 211,936 KB
実行使用メモリ 7,892 KB
最終ジャッジ日時 2023-09-20 23:27:06
合計ジャッジ時間 10,211 ms
ジャッジサーバーID
(参考情報)
judge14 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,376 KB
testcase_01 AC 1 ms
4,380 KB
testcase_02 AC 2 ms
4,376 KB
testcase_03 AC 1 ms
4,376 KB
testcase_04 AC 2 ms
4,376 KB
testcase_05 AC 1 ms
4,376 KB
testcase_06 AC 2 ms
4,380 KB
testcase_07 AC 2 ms
4,380 KB
testcase_08 AC 2 ms
4,376 KB
testcase_09 AC 2 ms
4,376 KB
testcase_10 AC 3 ms
4,376 KB
testcase_11 AC 3 ms
4,376 KB
testcase_12 AC 2 ms
4,376 KB
testcase_13 AC 42 ms
7,888 KB
testcase_14 AC 43 ms
7,796 KB
testcase_15 AC 562 ms
7,200 KB
testcase_16 AC 513 ms
6,996 KB
testcase_17 AC 397 ms
6,220 KB
testcase_18 AC 49 ms
6,412 KB
testcase_19 AC 51 ms
6,940 KB
testcase_20 AC 35 ms
7,004 KB
testcase_21 AC 993 ms
7,372 KB
testcase_22 AC 1,021 ms
7,272 KB
testcase_23 AC 998 ms
7,304 KB
testcase_24 AC 64 ms
6,836 KB
testcase_25 AC 114 ms
6,936 KB
testcase_26 AC 230 ms
6,504 KB
testcase_27 AC 171 ms
6,144 KB
testcase_28 AC 139 ms
6,740 KB
testcase_29 AC 37 ms
6,508 KB
testcase_30 AC 36 ms
6,464 KB
testcase_31 AC 36 ms
7,892 KB
testcase_32 AC 170 ms
7,268 KB
testcase_33 AC 172 ms
7,256 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#define For(i, a, b) for(int (i)=(int)(a); (i)<(int)(b); ++(i))
#define rFor(i, a, b) for(int (i)=(int)(a)-1; (i)>=(int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
template<class T> bool chmax(T &a, const T &b){if(a<b){a=b; return true;} return false;}
template<class T> bool chmin(T &a, const T &b){if(a>b){a=b; return true;} return false;}
template<class T> T div_floor(T a, T b){
    if(b < 0) a *= -1, b *= -1;
    return a>=0 ? a/b : (a+1)/b-1;
}
template<class T> T div_ceil(T a, T b){
    if(b < 0) a *= -1, b *= -1;
    return a>0 ? (a-1)/b+1 : a/b;
}

constexpr lint mod = 1000000007;
constexpr lint INF = mod * mod;
constexpr int MAX = 500010;

template<int_fast64_t MOD> struct modint{
    using i64=int_fast64_t;
    i64 a;
    modint(const i64 a_=0): a(a_){
        if(a>MOD) a%=MOD;
        else if(a<0) (a%=MOD)+=MOD;
    }
    modint inv(){
        i64 t=1, n=MOD-2, x=a;
        while(n){
            if(n&1) (t*=x)%=MOD;
            (x*=x)%=MOD;
            n>>=1;
        }
        modint ret(t);
        return ret;
    }
    bool operator==(const modint x) const{return a==x.a;}
    bool operator!=(const modint x) const{return a!=x.a;}
    modint operator+(const modint x) const{
        return modint(*this)+=x;
    }
    modint operator-(const modint x) const{
        return modint(*this)-=x;
    }
    modint operator*(const modint x) const{
        return modint(*this)*=x;
    }
    modint operator/(const modint x) const{
        return modint(*this)/=x;
    }
    modint operator^(const lint x) const{
        return modint(*this)^=x;
    }
    modint &operator+=(const modint &x){
        a+=x.a;
        if(a>=MOD) a-=MOD;
        return *this;
    }
    modint &operator-=(const modint &x){
        a-=x.a;
        if(a<0) a+=MOD;
        return *this;
    }
    modint &operator*=(const modint &x){
        (a*=x.a)%=MOD;
        return *this;
    }
    modint &operator/=(modint x){
        (a*=x.inv().a)%=MOD;
        return *this;
    }
    modint &operator^=(lint n){
        i64 ret=1;
        while(n){
            if(n&1) (ret*=a)%=MOD;
            (a*=a)%=MOD;
            n>>=1;
        }
        a=ret;
        return *this;
    }
    modint operator-() const{
        return modint(0)-*this;
    }
    modint &operator++(){
        return *this+=1;
    }
    modint &operator--(){
        return *this-=1;
    }
    bool operator<(const modint x) const{
        return a<x.a;
    }
};

using mint=modint<1000000007>;

vector<mint> fact;
vector<mint> revfact;

void setfact(int n){
    fact.resize(n+1); revfact.resize(n+1);
    fact[0] = 1;
    rep(i, n) fact[i+1] = fact[i] * mint(i+1);

    revfact[n] = fact[n].inv();
    for(int i=n-1; i>=0; i--) revfact[i] = revfact[i+1] * mint(i+1);
}

mint getC(int n, int r){
    if(n<r) return 0;
    return fact[n] * revfact[r] * revfact[n-r];
}

template<typename T, typename E, typename F, typename G>
struct SegTree{
    int sz = 1, seq_sz;
    T et;
    F f;
    G g;
    vector<T> node;

    SegTree(int sz_, T et, F f, G g): seq_sz(sz_), et(et), f(f), g(g){
        while(sz<sz_) sz <<= 1;
        node.resize(sz<<1, et);
    }

    void build(vector<T> &a){
        rep(i, a.size()) node[i+sz] = a[i];
        rFor(i, sz, 1) node[i] = f(node[i<<1], node[(i<<1)+1]);
    }

    void build(T x){
        rep(i, seq_sz) node[i+sz] = x;
        rFor(i, sz, 1) node[i] = f(node[i<<1], node[(i<<1)+1]);
    }

    void update(int i, E x){
        i += sz;
        node[i] = g(node[i], x);
        i >>= 1;
        while(i){
            node[i] = f(node[i<<1], node[(i<<1)+1]);
            i >>= 1;
        }
    }

    T query(int l, int r){
        T vl = et, vr = et;
        for(l+=sz, r+=sz; l<r; l>>=1, r>>=1){
            if(l&1) vl = f(vl, node[l++]);
            if(r&1) vr = f(node[--r], vr);
        }
        return f(vl, vr);
    }

    int search_left(int l, const T val, function<bool(T, T)> cmp, function<bool(T, T)> check){
        T sum = et;
        for(l+=sz; ; l>>=1){
            if(check(f(sum, node[l]), val)){
                while(l < sz){
                    if(check(f(sum, node[l<<1]), val)) l <<= 1;
                    else{
                        sum = f(sum, node[l<<1]);
                        l = (l<<1) + 1;
                    }
                }
                return l-sz;
            }
            if(__builtin_popcount(l+1) == 1) return seq_sz;
            if(l&1) sum = f(sum, node[l++]);
        }
    }

    int search_right(int r, const T val, function<bool(T, T)> cmp, function<bool(T, T)> check){
        T sum = et;
        for(r+=sz; ; r>>=1){
            if(check(f(sum, node[r]), val)){
                while(r < sz){
                    if(check(f(node[(r<<1)+1], sum), val)) r = (r<<1) + 1;
                    else{
                        sum = f(node[(r<<1)+1], sum);
                        r<<=1;
                    }
                }
                return r-sz;
            }
            if(__builtin_popcount(r) == 1) return -1;
            if(!(r&1)) sum = f(node[r--], sum);
        }
    }

    int lower_bound_left(int l, const T val, function<bool(T, T)> cmp=less<>()){
        auto check = [&cmp](auto a, auto b){return !cmp(a, b);};
        return search_left(l, val, cmp, check);
    }

    int upper_bound_left(int l, const T val, function<bool(T, T)> cmp=less<>()){
        auto check = [&cmp](auto a, auto b){return cmp(b, a);};
        return search_left(l, val, cmp, check);
    }

    int lower_bound_right(int l, const T val, function<bool(T, T)> cmp=greater<>()){
        auto check = [&cmp](auto a, auto b){return !cmp(b, a);};
        return search_right(l, val, cmp, check);
    }

    int upper_bound_right(int l, const T val, function<bool(T, T)> cmp=greater<>()){
        auto check = [&cmp](auto a, auto b){return cmp(a, b);};
        return search_right(l, val, cmp, check);
    }
};

int main(){
    int h, w;
    scanf("%d%d", &h, &w);
    mint b[h][w];
    rep(i, h)rep(j, w) scanf("%lld", &b[i][j]);
    bool trans = (h > w);
    vector<vector<mint>> a;
    if(trans){
        a.resize(w);
        rep(i, w){
            a[i].resize(h);
            rep(j, h) a[i][j] = b[j][i];
        }
        swap(h, w);
    }
    else{
        a.resize(h);
        rep(i, h){
            a[i].resize(w);
            rep(j, w) a[i][j] = b[i][j];
        }
    }

    vector<SegTree<mint, mint, decltype(multiplies<>()), decltype(multiplies<>())>> st(h, {w, 1, multiplies<>(), multiplies<>()});
    rep(i, h) st[i].build(a[i]);

    int q;
    scanf("%d", &q);
    rep(_, q){
        int r, c;
        scanf("%d%d", &r, &c);
        --r; --c;
        if(trans) swap(r, c);
        mint ans = 1;
        rep(i, h)if(i != r){
            ans *= st[i].query(0, c);
            ans *= st[i].query(c+1, w);
            if(ans == 0) break;
        }
        printf("%lld\n", ans.a);
    }
}
0