开始完全没思路

在洛谷看到样例一,突发奇想,决定先做一下元素只有0/1的情况

发现子任务1是全1子矩阵

子任务2是总子矩阵个数减去全0子矩阵

发现全0/1矩阵可以构造单调栈解决。具体做法:前缀和求出每个格子上面有多少颜色为0/1的格子(是0是1有求子任务1/2决定),然后发现可以每次在单调栈中找出相邻的两个值,算出内部区块的面积,多次累加后发现刚好是全0/1子矩阵的个数

小技巧:把单调队列的第0项的坐标置0,可以避免特判

让后求总子矩阵个数也很简单,递推解决(我数学不好,瑟瑟发抖)

公式:  ff[i][j] = ff[i - 1][j] + ff[i][j - 1] - ff[i - 1][j - 1] + i * j;

那么总子矩阵个数即为f[n][n]

让后向元素任意值得矩阵迈进

发现恰好可以以二进制来展开获得0/1矩阵

代码:

for (register int i = 0; i < n; ++i)
    for (register int j = 0; j < n; ++j)
        a[i][j] = (atot[i][j] & (1 << flr)) ? 1 : 0;

atot为读入数组,a为需要的0/1数组

flr表示现在在二进制的flr位

让后算出来的答案乘以(1 << flr)累加到总答案上

打完以后发现30分

快速浏览代码没找到错误(我太菜了)

后来点开了题解,正准备浏jie览jian,突然发现有一处没有MOD,

MOD了以后果断(???)AC...

贴个代码

#include <cstdio>
#define ll long long const ll MOD = 1e9+; inline ll read(){
ll x = ; int zf = ; char ch = ' ';
while (ch != '-' && (ch < '' || ch > '')) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (ch >= '' && ch <= '') x = x * + ch - '', ch = getchar(); return x * zf;
} ll atot[][];
int a[][];
int sum[][]; ll ff[][]; ll or_init; struct Node{
ll pos;
ll hei;
} ddstk[];
int top; int main(){
int n = read();
for (register int i = ; i < n; ++i)
for (register int j = ; j < n; ++j)
atot[i][j] = read();
for (register int i = ; i <= n; ++i){
for (register int j = ; j <= n; ++j){
ff[i][j] = ff[i - ][j] + ff[i][j - ] - ff[i - ][j - ] + i * j;
if (ff[i][j] < )
ff[i][j] += MOD;
ff[i][j] %= MOD;
}
}
or_init = ff[n][n];
ll ans1 = , cur_ans1, ans2 = , cur_ans2;
ddstk[].pos = ;
for (int flr = ; flr < ; ++flr){
for (register int i = ; i < n; ++i)
for (register int j = ; j < n; ++j)
a[i][j] = (atot[i][j] & ( << flr)) ? : ;
//getAnd
for (register int i = ; i < n; ++i)
for (register int j = ; j < n; ++j)
if (i != )
sum[i][j] = (a[i][j] == ) ? sum[i - ][j] + : ;
else
sum[i][j] = (a[i][j] == ) ? : ;
cur_ans1 = ;
for (register int i = ; i < n; ++i){
top = ;
for (register int k = ; k < n; ++k){
while (top){
if (sum[i][k] <= ddstk[top].hei)
--top;
else
break;
}
ddstk[++top].pos = k + ;
ddstk[top].hei = sum[i][k];
for (int l = top; l >= ; --l){
cur_ans1 += ddstk[l].hei * (ddstk[l].pos - ddstk[l - ].pos);
cur_ans1 %= MOD;
}
}
}
ans1 += (cur_ans1 * ((1ll << flr) % MOD)) % MOD;
ans1 %= MOD;
//getOr
for (register int i = ; i < n; ++i)
for (register int j = ; j < n; ++j)
if (i != )
sum[i][j] = (a[i][j] == ) ? sum[i - ][j] + : ;
else
sum[i][j] = (a[i][j] == ) ? : ;
cur_ans2 = ;
for (register int i = ; i < n; ++i){
top = ;
for (register int k = ; k < n; ++k){
while (top){
if (sum[i][k] <= ddstk[top].hei)
--top;
else
break;
}
ddstk[++top].pos = k + ;
ddstk[top].hei = sum[i][k];
for (int l = top; l >= ; --l){
cur_ans2 += ddstk[l].hei * (ddstk[l].pos - ddstk[l - ].pos);
cur_ans2 %= MOD;
}
}
}
cur_ans2 = (or_init - cur_ans2 + MOD) % MOD;
ans2 += (cur_ans2 * ((1ll << flr) % MOD)) % MOD;
ans2 %= MOD;
}
printf("%lld %lld", ans1, ans2);
return ;
}

题解:[GXOI/GZOI2019]与或和的更多相关文章

  1. 题解-GXOI/GZOI2019 特技飞行

    Problem loj3085 bzoj不放题面差评 题意概要:给出两条竖直直线,再给出 \(n\) 架飞机的初始航线:一条接通这两条直线的线段,保证航线交点不在两条直线上.现要求安排所有飞机在航线相 ...

  2. GXOI/GZOI2019题解

    GXOI/GZOI2019题解 P5300 [GXOI/GZOI2019]与或和 一眼题.. 显然枚举每个二进制位,答案就变成了全1子矩阵数量. 这个xjb推推,单调栈一下就行了. #include& ...

  3. 「GXOI / GZOI2019」简要题解

    「GXOI / GZOI2019」简要题解 LOJ#3083. 「GXOI / GZOI2019」与或和 https://loj.ac/problem/3083 题意:求一个矩阵的所有子矩阵的与和 和 ...

  4. 【BZOJ5505】[GXOI/GZOI2019]逼死强迫症(矩阵快速幂)

    [BZOJ5505][GXOI/GZOI2019]逼死强迫症(矩阵快速幂) 题面 BZOJ 洛谷 题解 如果没有那两个\(1*1\)的东西,答案就是斐波那契数,可以简单的用\(dp\)得到. 大概是设 ...

  5. P5305 [GXOI/GZOI2019]旧词

    题目地址:P5305 [GXOI/GZOI2019]旧词 这里是官方题解 \[\sum_{i \leq x}^{}\ depth(lca(i,y))^k\] \(k = 1\) 求的是 \(\sum_ ...

  6. P5304 [GXOI/GZOI2019]旅行者

    题目地址:P5304 [GXOI/GZOI2019]旅行者 这里是官方题解 一个图 \(n\) 点 \(m\) 条边,里面有 \(k\) 个特殊点,问这 \(k\) 个点之间两两最短路的最小值是多少? ...

  7. P5303 [GXOI/GZOI2019]逼死强迫症

    题目地址:P5303 [GXOI/GZOI2019]逼死强迫症 这里是官方题解 初步分析 从题目和数据范围很容易看出来这是一个递推 + 矩阵快速幂,那么主要问题在于递推的过程. 满足条件的答案一定是以 ...

  8. P5302 [GXOI/GZOI2019]特技飞行

    题目地址:P5302 [GXOI/GZOI2019]特技飞行 这里是官方题解(by lydrainbowcat) 题意 给 \(10^5\) 条直线,给 \(x = st\) 和 \(x = ed\) ...

  9. P5301 [GXOI/GZOI2019]宝牌一大堆

    题目地址:P5301 [GXOI/GZOI2019]宝牌一大堆 这里是官方题解(by lydrainbowcat) 部分分 直接搜索可以得到暴力分,因为所有和牌方案一共只有一千万左右,稍微优化一下数据 ...

随机推荐

  1. docker的基本知识

    Docker 是什么? Docker 是一个开源的应用容器引擎,是基于go语言的,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化. ...

  2. bzoj4892 [TJOI2017]DNA

    bzoj4892 [TJOI2017]DNA 给定一个匹配串和一个模式串,求模式串有多少个连续子串能够修改不超过 \(3\) 个字符变成匹配串 \(len\leq10^5\) hash 枚举子串左端点 ...

  3. 你所不知道的ASP.NET Core MVC/WebApi基础系列(二)

    前言 好久没冒泡了,算起来估计有快半年没更新博客了,估计是我第一次停更如此之久,人总有懒惰的时候,时间越长越懒惰,但是呢,不学又不行,持续的惰性是不行dei,要不然会被时光所抛弃,技术所淘汰,好吧,进 ...

  4. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案

    ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不大,但从内部运行方式上来说,差别还是很大的.上一篇详细介绍了原版路由方案的运行机制, ...

  5. 使用队列实现栈(2)(Java)

    class MyStack { private Queue q1; private Queue q2; public MyStack(int size) { this.q1 = new Queue(s ...

  6. [题解]图的m着色问题

    图的m着色问题(color) [题目描述] 给定无向连通图G和m种不同的颜色.用这些颜色为图G的各顶点着色,每个顶点着一种颜色.如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的 ...

  7. 米卡 Mica Logo 存放处

  8. 洛谷 P1962 斐波那契数列

    题目链接:https://www.luogu.org/problemnew/show/P1962 题目大意: 略 分析: 由于数据规模很大,需要用矩阵快速幂来解. 代码如下: #pragma GCC ...

  9. springboot使用RestHighLevelClient批量插入

    1.引入maven(注意版本要一致) <dependency> <groupId>org.springframework.boot</groupId> <ar ...

  10. 深度学习结合SLAM研究总结

    博客转载自:https://blog.csdn.net/u010821666/article/details/78793225 原文标题:深度学习结合SLAM的研究思路/成果整理之 1. 深度学习跟S ...