zoukankan      html  css  js  c++  java
  • luogu P5300 [GXOI/GZOI2019]与或和

    传送门

    题目涉及按位与以及按位或运算,所以可以拆位考虑,枚举某个二进制位,然后某个位置如果那个数的第(i)位是(0)就放(0),否则放(1),这一位的贡献就是位运算后值为(1)的子矩阵个数(*2^i).对于与运算,权值为(1)的矩阵为全(1)矩阵;对于或运算,权值为(1)的矩阵为含有(1)的矩阵,可以看成是总个数-全(0)矩阵个数,然后全(0)和全(1)矩阵个数可以单调栈求得

    #include<bits/stdc++.h>
    #define LL long long
    #define db long double
    #define il inline
    
    using namespace std;
    const int N=1e3+10,mod=1e9+7;
    il LL rd()
    {
        LL x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int n,a[N][N],a1,a2,sm,b[N][N],c[N][N],st[N],tp;
    
    int main()
    {
        n=rd();
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
            {
                a[i][j]=rd();
                sm=(sm+1ll*(n-i+1)*(n-j+1)%mod)%mod;
            }
        for(int h=30;~h;--h)
        {
            bool o=0;
            for(int i=1;i<=n;++i)
                for(int j=1;j<=n;++j)
                {
                    int x=a[i][j]>>h&1;
                    o|=x;
                    b[i][j]=x?b[i-1][j]+1:0,c[i][j]=!x?c[i-1][j]+1:0;
                }
            if(!o) continue;
            int cn=0,na;
            for(int i=1;i<=n;++i)
            {
                tp=0,na=0;
                for(int j=1;j<=n;++j)
                {
                    while(tp&&b[i][st[tp]]>b[i][j]) na=(na-1ll*(st[tp]-st[tp-1])*b[i][st[tp]]%mod+mod)%mod,--tp;
                    st[++tp]=j,na=(na+1ll*(st[tp]-st[tp-1])*b[i][st[tp]]%mod)%mod;
                    cn=(cn+na)%mod;
                }
            }
            a1=(a1+(1ll<<h)*cn%mod)%mod;
            cn=0;
            for(int i=1;i<=n;++i)
            {
                tp=0,na=0;
                for(int j=1;j<=n;++j)
                {
                    while(tp&&c[i][st[tp]]>c[i][j]) na=(na-1ll*(st[tp]-st[tp-1])*c[i][st[tp]]%mod+mod)%mod,--tp;
                    st[++tp]=j,na=(na+1ll*(st[tp]-st[tp-1])*c[i][st[tp]]%mod)%mod;
                    cn=(cn+na)%mod;
                }
            }
            a2=(a2+(1ll<<h)*(1ll*sm-cn+mod)%mod)%mod;
        }
        printf("%d %d
    ",a1,a2);
        return 0; 
    }
    
  • 相关阅读:
    Android Wifi简单管理与操作
    Android 语音识别(其它资料里面的代码)
    Android 读取资源文件下面的文件
    slice,substr和substring的区别
    !important minheight
    Jquery之美中不足之三delegate的缺憾
    事件切片
    QWrap简介之:apps果实篇之:定制
    QWrap简介之:apps果实篇之:小结
    QWrap简介之:结语
  • 原文地址:https://www.cnblogs.com/smyjr/p/10762929.html
Copyright © 2011-2022 走看看