[luogu 5300][bzoj 5502] [GXOI/GZOI2019] 与或和
题面
思路还是挺容易想的, 只是由于我还是太\(naive\)了一点不会做只会打暴力吧......
题目要我们求所有子矩阵的\(and\)值之和与\(or\)值之和, 一看之下似乎不好入手, 我们慢慢来.
由于\(and\)和\(or\)运算都是对于每个数的同一位二进制位进行运算的, 所以我们考虑将每个数拆成二进制数, 一位一位地统计答案, 这样的话, 原矩阵就变成了\(log{n}\)个01矩阵, 我们考虑先从\(and\)值入手.
关于\(and\)值
由于是01矩阵, 对于最终答案有贡献的子矩阵必然所有元素都为1, 也就是说, 题目让我们求在一个\(n*m\)的矩阵中全为1的子矩阵有多少个. 这不是极大子矩阵的裸题吗, 考虑使用单调栈, 没有学过的左转百度吧(我也是昨天听\(lzf\)同志讲了我才知道的).
关于\(or\)值
其实差不多, 对答案没有贡献的矩形就是那些全部为0的矩形, 用所有的情况减掉就是了, 还是单调栈(熟悉的配方)
然后大体上题目分析就到这里了, 每一位复杂度是\(O(n ^ 2)\), 总复杂度为\(O(n ^ 2log{n})\), 下面是代码的具体实现:
#include <iostream>
#include <cstring>
#include <cstdio>
#define N 1005
#define mod 1000000007
using namespace std;
int n, mp[N][N], s[N], w[N], h[N], top = 0;
long long ans[2];
inline int read()
{
int x = 0, w = 1;
char c = getchar();
while(c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * w;
}
long long get_num(int x) { return (1ll * x * (x + 1)) >> 1; }
long long get_ans(int x)
{
long long res = 0;
top = 0;
for(int i = 1; i <= n; i++) h[i] = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if((mp[i][j] & 1) == x) h[j]++;
else h[j] = 0;
if(h[j] > s[top]) { s[++top] = h[j]; w[top] = 1; }
else
{
int k = 0;
while(s[top] > h[j])
{
k += w[top];
res = (res + (s[top] - max(s[top - 1], h[j])) * get_num(k) % mod) % mod;
top--;
}
s[++top] = h[j]; w[top] = k + 1;
}
}
int k = 0;
while(top)
{
k += w[top];
res = (res + (s[top] - s[top - 1]) * get_num(k) % mod) % mod;
top--;
}
}
return (res % mod + mod) % mod;
//单调栈实现极大子矩阵, 其实用悬线法也可以, 但是我既不会单调栈, 悬线法也没用过几次, 于是就成功Oho了
}
void work(int x)
{
if(x == 32) return;
ans[0] = (ans[0] + get_ans(1) * (1 << x) % mod) % mod;
ans[1] = (ans[1] + (get_num(n) * get_num(n) % mod - get_ans(0)) * (1 << x) % mod) % mod;
//注意这个地方1左移x位是因为若不把这个数拆位的话其实这个数的这一位贡献是(1 << x)的.
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
mp[i][j] >>= 1;
work(x + 1);
}
int main()
{
n = read();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
mp[i][j] = read();
work(0);
printf("%lld %lld\n", (ans[0] + mod) % mod, (ans[1] + mod) % mod);
return 0;
}
[luogu 5300][bzoj 5502] [GXOI/GZOI2019] 与或和的更多相关文章
- [luogu 5301][bzoj 5503] [GXOI/GZOI2019] 宝牌一大堆
题面 好像ZJOI也考了一道麻将, 这是要发扬中华民族的赌博传统吗??? 暴搜都不会打, 看到题目就自闭了, 考完出来之后看题解, \(dp\), 可惜自己想不出来... 对于国士无双(脑子中闪过了韩 ...
- 「洛谷5300」「GXOI/GZOI2019」与或和【单调栈+二进制转化】
题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include & ...
- 【BZOJ5505】[GXOI/GZOI2019]逼死强迫症(矩阵快速幂)
[BZOJ5505][GXOI/GZOI2019]逼死强迫症(矩阵快速幂) 题面 BZOJ 洛谷 题解 如果没有那两个\(1*1\)的东西,答案就是斐波那契数,可以简单的用\(dp\)得到. 大概是设 ...
- 题解-GXOI/GZOI2019 特技飞行
Problem loj3085 bzoj不放题面差评 题意概要:给出两条竖直直线,再给出 \(n\) 架飞机的初始航线:一条接通这两条直线的线段,保证航线交点不在两条直线上.现要求安排所有飞机在航线相 ...
- 【BZOJ5502】[GXOI/GZOI2019]与或和(单调栈)
[BZOJ5502][GXOI/GZOI2019]与或和(单调栈) 题面 BZOJ 洛谷 题解 看到位运算就直接拆位,于是问题变成了求有多少个全\(0\)子矩阵和有多少个全\(1\)子矩阵. 这两个操 ...
- 【BZOJ5503】[GXOI/GZOI2019]宝牌一大堆(动态规划)
[BZOJ5503][GXOI/GZOI2019]宝牌一大堆(动态规划) 题面 BZOJ 洛谷 题解 首先特殊牌型直接特判. 然后剩下的部分可以直接\(dp\),直接把所有可以存的全部带进去大力\(d ...
- 【BZOJ5506】[GXOI/GZOI2019]旅行者(最短路)
[BZOJ5506][GXOI/GZOI2019]旅行者(最短路) 题面 BZOJ 洛谷 题解 正着做一遍\(dij\)求出最短路径以及从谁转移过来的,反过来做一遍,如果两个点不由同一个点转移过来就更 ...
- 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)
[BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...
- [LOJ3087][GXOI/GZOI2019]旅行者——堆优化dijkstra
题目链接: [GXOI/GZOI2019]旅行者 我们考虑每条边的贡献,对每个点求出能到达它的最近的感兴趣的城市(设为$f[i]$,最短距离设为$a[i]$)和它能到达的离它最近的感兴趣的城市(设为$ ...
随机推荐
- 菜鸟入门【ASP.NET Core】13:Individual authentication 模板、EF Core Migration
Individual authentication 模板 我们首先用VSCode新建一个mvc的网站,这个网站创立的时候回自动为我们创建Identuty Core以及EF Core的代码示例,我们可以 ...
- 使用 Immutable Subject 来驱动 Angular 应用
现状 最近在重构手上的一个 Angular 项目,之前是用的自己写的一个仿 Elm 架构的库来进行的状态管理,期间遇到了这些痛点: 样板代码太多 异步处理太过繁琐 需要单独维护一个 npm 包 其中, ...
- linux下使用gcc编译运行C/C++程序
编译C 首先,程序编译过程有: 1.预处理(展开宏,头文件,检查代码是否有误) 2.编译(将.c转为汇编代码.s) 3.汇编(将汇编代码.s转为机器代码.o) 4.链接(将所有机器代码.o和库文件链 ...
- Java语言的简介
Java语言的由来 Java是由Sun Microsystems公司推出的Java面向对象程序设计语言(以下简称Java语言)和Java平台的总称.由James Gosling和同事们共同研发,并在1 ...
- 了解java虚拟机—G1回收器(9)
G1(Garbage-First)回收器是在JDK1.7中正式使用的全新垃圾回收器,G1拥有独特的垃圾回收策略,从分代上看,G1依然属于分代垃圾回收器,它会区分年代和老年代,依然有eden和survi ...
- SSM(Spring+SpringMvc+Mybatis)整合笔记
1.使用开发工具 jdk1.8 eclipse Tomcat7.0 MySql 2.创建数据库和表,由于重点是整合,所以数据库就随意加几条数据. 3.创建动态Web项目(推荐使用Maven可以用配置来 ...
- js .map方法
map这里的map不是“地图”的意思,而是指“映射”.[].map(); 基本用法跟forEach方法类似: array.map(callback,[ thisObject]); callback的参 ...
- CentOS 通过yum来升级php到php5.6,yum upgrade php 没有更新包
在文章中,我们将展示在centOS系统下如何将php升级到5.6,之前通过yum来安装lamp环境,直接升级的话,提示没有更新包,也就是说默认情况下php5.3.3是最新 1.查看已经安装的php版本 ...
- 《Inside C#》笔记(八) 接口
接口可以认为是属于不同继承树的代码之间的行为约定.C#的接口相当于是一种特殊的抽象类,这种抽象类的内部只有虚方法. 一 接口的使用 a) 接口内部可以包含方法.属性.索引器和事件,这些成员都不在接口中 ...
- [20171128]rman Input or output Memory Buffers.txt
[20171128]rman Input or output Memory Buffers.txt --//做一个简单测试rman 的Input or output Memory Buffers. 1 ...