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\n",a1,a2);
return 0;
}
luogu P5300 [GXOI/GZOI2019]与或和的更多相关文章
- 【题解】Luogu P5300 [GXOI/GZOI2019]与或和
原题传送门 我们珂以拆位,拆成一个个0/1矩阵 贡献珂以用全0,全1的子矩阵的个数来计算 全0,全1的子矩阵的个数珂以用悬线法/单调栈解决 #include <bits/stdc++.h> ...
- P5300 [GXOI/GZOI2019]与或和
题目地址:P5300 [GXOI/GZOI2019]与或和 考虑按位计算贡献 对于 AND 运算,只有全 \(1\) 子矩阵才会有贡献 对于 OR 运算,所以非全 \(0\) 子矩阵均有贡献 如果求一 ...
- luogu P5305 [GXOI/GZOI2019]旧词
传送门 先考虑\(k=1\),一个点的深度就是到根节点的路径上的点的个数,所以\(lca(x,y)\)的深度就是\(x\)和\(y\)到根路径的交集路径上的点的个数,那么对于一个询问,我们可以对每个点 ...
- luogu P5304 [GXOI/GZOI2019]旅行者
传送门 所以这个\(5s\)是SMG 暴力是枚举每一个点跑最短路,然后有一个很拿衣服幼稚的想法,就是把所有给出的关键点当出发点,都丢到队列里,求最短路的时候如果当前点\(x\)某个相邻的点\(y\)是 ...
- luogu P5303 [GXOI/GZOI2019]逼死强迫症
传送门 只有两行,考虑递推,设\(f_i\)为没有那两个\(1*1\)的,前\(i\)列的方案,可以发现一次可以放一个竖的或两个横的,也就是\(f_i=f_{i-1}+f_{i-2}\) 再设\(g_ ...
- luogu P5302 [GXOI/GZOI2019]特技飞行
传送门 强行二合一可还行 首先\(c\)的贡献是不会变的,先考虑求出多少交点被矩形覆盖,交点的话可以按左端点纵坐标从下到上顺序枚举一条线段,然后维护右端点纵坐标的set,把之前处理过线段的右端点放进s ...
- luogu P5301 [GXOI/GZOI2019]宝牌一大堆
传送门 wdnm又是打麻将 首先国土无双可以直接枚举哪种牌用了\(2\)次算贡献,然后\(7\)个对子可以把每种牌的对子贡献排序,取最大的\(7\)个,剩下的牌直接暴力枚举是不行的,考虑dp,设\(f ...
- 【题解】Luogu P5301 [GXOI/GZOI2019]宝牌一大堆
原题传送门 首先先要学会麻将,然后会发现就是一个暴力dp,分三种情况考虑: 1.非七对子国士无双,设\(dp_{i,j,k,a,b}\)表示看到了第\(i\)种牌,一共有\(j\)个\(i-1\)开头 ...
- 【题解】Luogu P5304 [GXOI/GZOI2019]旅行者
原题传送门 题意:给你k个点,让你求两两最短路之间的最小值 我们考虑二进制拆分,使得每两个点都有机会分在不同的组\((A:0,B:1)\)中,从源点\(S\)向\(A/B\)中的点连边权为0的边,从\ ...
随机推荐
- Ubuntu 下重启网络的方法
命令是: sudo /etc/init.d/networking restart 但是可能会遇到下面的提示: Running /etc/init.d/networking restart is dep ...
- android系统中如何通过程序打开某个AccessibilityService
android系统中如何通过程序打开某个AccessibilityService(系统辅助服务)? 通常的做法是注册AccessibilityService(辅助服务)后跳转到设置启动服务页面引导用户 ...
- 好程序员技术教程分享JavaScript运动框架
好程序员技术教程分享JavaScript运动框架,有需要的朋友可以参考下. JavaScript的运动,即让某元素的某些属性由一个值变到另一个值的过程.如让div的width属性由200px变到400 ...
- centos7 安装mysql5.7
[root@izbp1buyhgwtrvlxv3u2gqz soft]# wget http://dev.mysql.com/get/mysql57-community-release-el7-8.n ...
- iOS开发基础-九宫格坐标(1)
一.功能分析 1)以九宫格展示图片信息,每一个 UIView 包含一个 UIImageView .一个 UILabel 和一个 UIButton . 2)加载App数据,根据数据长度创建对应的格子数: ...
- 【原创】分布式之大话CAP
引言 本文翻译自博客 http://ksat.me/a-plain-english-introduction-to-cap-theorem/ 博主觉得这个故事讲的生动活泼,因此翻译来给大家分享,顺便加 ...
- 关于JAVA中string直接初始化赋值和new的区别,是否可以联系到int[]的情况
String str1 = "ABC"; String str2 = new String("ABC"); String str1 = “ABC”;可能创建一个 ...
- python 支付宝SDK
python 支付宝SDK代码如下 from datetime import datetime from Crypto.PublicKey import RSA from Crypto.Signatu ...
- nginx中的epoll模型
要了解epoll模型,就要一个一个知识点由浅至深地去探索. 1.IO复用技术 IO流请求操作系统内核,有串行处理和并行处理两种概念. 串行处理是前面一个操作处理地时候,后面的所有操作都需要等待.因此, ...
- php函数 array_change_key_cash
array_change_key_case ( array $array [, int $case = CASE_LOWER ] ) : array array_change_key_case() 将 ...