zoukankan      html  css  js  c++  java
  • 洛谷P5300 与或和(全1子矩阵/单调栈)

    洛谷P5300 与或和

    题目链接

    按照二进制将矩阵转换为32个01矩阵,and和就是一个01矩阵中全1子矩阵的个数乘以当前矩阵的贡献值,or和就是(总子矩阵个数-全0子矩阵的个数)*当前矩阵的贡献值。

    #include "bits/stdc++.h"
    
    using namespace std;
    typedef long long ll;
    const int mod = 1e9 + 7;
    const int maxn = 1e3 + 100;
    bool d[35][maxn][maxn];
    ll num[maxn][maxn];
    ll st[maxn], tot, up[maxn], down[maxn];
    int n;
    
    void getnum(int k, int op) {//op为0时计算1的个数
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                num[i][j] = (d[k][i][j] ^ op) ? num[i][j - 1] + 1 : 0;
            }
        }
    }
    
    ll getcnt() {
        ll ret = 0;
        for (int j = 1; j <= n; j++) {
            tot = 0;
            for (int i = 1; i <= n; i++) {
                if (num[i][j]) {
                    up[i] = 1;
                    while (tot && num[i][j] <= num[st[tot]][j]) {
                        up[i] += up[st[tot]];
                        tot--;
                    }
                    st[++tot] = i;
                } else {
                    up[i] = 0;
                    tot = 0;
                }
            }
            tot = 0;
            for (int i = n; i >= 1; i--) {
                if (num[i][j]) {
                    down[i] = 1;
                    while (tot && num[i][j] < num[st[tot]][j]) {
                        down[i] += down[st[tot]];
                        tot--;
                    }
                    st[++tot] = i;
                } else {
                    down[i] = 0;
                    tot = 0;
                }
                ret = (ret + up[i] * down[i] * num[i][j] % mod) % mod;
            }
        }
        return (ret + mod) % mod;
    }
    
    ll p[35];
    
    int main() {
        //freopen("in.txt", "r", stdin);
        cin >> n;
        ll x, nn = 0;
        p[0] = 1;
        for (int i = 1; i <= 32; i++) {
            p[i] = p[i - 1] * 2 % mod;
        }
    
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                nn = (nn + i * j) % mod;
                cin >> x;
                for (int k = 0; k <= 32; k++) {
                    if (x & (1ll << k)) {
                        d[k][i][j] = true;
                    }
                }
            }
        }
        ll ansand = 0, ansor = 0;
        for (int k = 0; k <= 32; k++) {
            getnum(k, 0);
            ansand = (ansand + p[k] * getcnt() % mod) % mod;
            getnum(k, 1);
            ansor = (ansor + p[k] * (nn - getcnt() + mod) % mod) % mod;
        }
        cout << ansand << " " << ansor << endl;
        return 0;
    }
    
  • 相关阅读:
    网站备份list
    vnc checklist
    appnode iptables 规则后面覆盖前面的
    Appnode + Discuz checklist
    解决WORD文档无法显示链接的图像问题
    应用容器Application container
    要研究的内容
    转 Flex MXML编译成AS类
    Flex文件结构
    int a
  • 原文地址:https://www.cnblogs.com/albert-biu/p/10867702.html
Copyright © 2011-2022 走看看