• 【LOJ】#3083. 「GXOI / GZOI2019」与或和


    LOJ#3083. 「GXOI / GZOI2019」与或和

    显然是先拆位,AND的答案是所有数字为1的子矩阵的个数

    OR是所有的子矩阵个数减去所有数字为0的子矩阵的个数

    子矩阵怎么求可以记录每个位置能向上延伸的高度(h[i][j])

    枚举左下角的端点,用一个单调栈维护即可

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define MAXN 100005
    #define ba 47
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    const int MOD = 1000000007;
    int N,all;
    int a[1005][1005],b[1005][1005],ans[2],h[1005],sta[1005],top;
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int mul(int a,int b) {
        return 1LL * a * b % MOD;
    }
    void update(int &a,int b) {
        a = inc(a,b);
    }
    int getall(int x) {
        memset(h,0,sizeof(h));
        int res = 0,sum = 0;
        for(int i = 1 ; i <= N ; ++i) {
    	sum = 0;top = 0;sta[0] = N + 1;
    	for(int j = N ; j >= 1 ; --j) {
    	    if(b[i][j] == x) h[j]++;
    	    else h[j] = 0;
    	    while(top && h[sta[top]] >= h[j]) {
    		update(sum,MOD - mul(sta[top - 1] - sta[top],h[sta[top]]));
    		--top;
    	    }
    	    sta[++top] = j;
    	    update(sum,mul(sta[top - 1] - sta[top],h[j]));
    	    update(res,sum);
    	}
        }
        return res;
    }
    void Solve() {
        read(N);
        for(int i = 1 ; i <= N ; ++i) {
    	for(int j = 1 ; j <= N ; ++j) {
    	    read(a[i][j]);
    	    update(all,mul(N - i + 1,N - j + 1));
    	}
        }
        for(int i = 30 ; i >= 0 ; --i) {
    	for(int j = 1 ; j <= N ; ++j) {
    	    for(int h = 1 ; h <= N ; ++h) {
    		b[j][h] = a[j][h] >> i & 1;
    	    }
    	}
    	int t = (1 << i) % MOD;
    	update(ans[0],mul(t,getall(1)));
    	update(ans[1],mul(t,inc(all,MOD - getall(0))));
        }
        out(ans[0]);space;out(ans[1]);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    
  • 相关阅读:
    Microsoft Web Camp
    [程序员学英语]26个英文字母
    原来接口是这样用的!一个例子搞定接口
    BizTalk Server 2010 培训
    [PM Tools]软件项目进度跟踪表v4.0
    BizTalk 开发系列(四十一) BizTalk 2010 BAM 安装手记
    WCF服务编程HelloWorld
    BizTalk 开发系列(三十九) BizTalk Server 2009技术概览
    WCF服务编程WCF应用程序的消息跟踪
    WCF服务编程基础
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10976403.html
Copyright © 2020-2023  润新知