zoukankan      html  css  js  c++  java
  • [GX/GZOI2019]与或和(单调栈+按位运算)

    首先看到与或,很显然想到按照位拆分运算。然后就变成了0/1矩阵,要使矩阵在当前位与为1,则矩阵全为1,如果是或为1,则是矩阵不全为0,然后求全为0/1的矩阵个数即可。记录c[i][j]表示以a[i][j]在该位向上0/1的长度。然后对于每一行,单调栈求解即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1003,mod=1e9+7;
    int n,ans1,ans2,top,a[N][N],b[N][N],c[N][N],st[N],sum[N];
    int calc()
    {
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        c[i][j]=b[i][j]?c[i-1][j]+1:0;
        int ret=0;
        for(int i=1;i<=n;i++)
        {
            st[0]=top=0;
            for(int j=1;j<=n;j++)
            if(!c[i][j])st[0]=j,top=0;
            else{
                while(top&&c[i][j]<=c[i][st[top]])top--;
                st[++top]=j,sum[top]=(sum[top-1]+1ll*(j-st[top-1])*c[i][j])%mod;
                ret=(ret+sum[top])%mod;
            }
        }
        return ret;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        scanf("%d",&a[i][j]);
        for(int t=0;t<=30;t++)
        {
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            b[i][j]=(a[i][j]>>t)&1;
            ans1=(ans1+(1ll<<t)*calc())%mod;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            b[i][j]^=1;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            ans2=(ans2+1ll*(n-i+1)*(n-j+1)%mod*(1ll<<t))%mod;
            ans2=(ans2-(1ll<<t)*calc()%mod+mod)%mod;
        }
        printf("%d %d",ans1,ans2);
    }
    View Code
  • 相关阅读:
    javascript ext 闭包
    Hibernate HQL from superclass 问题
    sql查询按in顺序排序显示数据 oracle
    Hibernate createSQLquery()
    sql 分页
    javasript 闭包测试
    Excel 批量快速导入mySQL 解决方案~~
    C# 注册COM+组件步骤~
    QT错误集锦~
    QuartzNet Test~~
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10852851.html
Copyright © 2011-2022 走看看