题解:[GXOI/GZOI2019]与或和
开始完全没思路
在洛谷看到样例一,突发奇想,决定先做一下元素只有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]与或和的更多相关文章
- 题解-GXOI/GZOI2019 特技飞行
Problem loj3085 bzoj不放题面差评 题意概要:给出两条竖直直线,再给出 \(n\) 架飞机的初始航线:一条接通这两条直线的线段,保证航线交点不在两条直线上.现要求安排所有飞机在航线相 ...
- GXOI/GZOI2019题解
GXOI/GZOI2019题解 P5300 [GXOI/GZOI2019]与或和 一眼题.. 显然枚举每个二进制位,答案就变成了全1子矩阵数量. 这个xjb推推,单调栈一下就行了. #include& ...
- 「GXOI / GZOI2019」简要题解
「GXOI / GZOI2019」简要题解 LOJ#3083. 「GXOI / GZOI2019」与或和 https://loj.ac/problem/3083 题意:求一个矩阵的所有子矩阵的与和 和 ...
- 【BZOJ5505】[GXOI/GZOI2019]逼死强迫症(矩阵快速幂)
[BZOJ5505][GXOI/GZOI2019]逼死强迫症(矩阵快速幂) 题面 BZOJ 洛谷 题解 如果没有那两个\(1*1\)的东西,答案就是斐波那契数,可以简单的用\(dp\)得到. 大概是设 ...
- P5305 [GXOI/GZOI2019]旧词
题目地址:P5305 [GXOI/GZOI2019]旧词 这里是官方题解 \[\sum_{i \leq x}^{}\ depth(lca(i,y))^k\] \(k = 1\) 求的是 \(\sum_ ...
- P5304 [GXOI/GZOI2019]旅行者
题目地址:P5304 [GXOI/GZOI2019]旅行者 这里是官方题解 一个图 \(n\) 点 \(m\) 条边,里面有 \(k\) 个特殊点,问这 \(k\) 个点之间两两最短路的最小值是多少? ...
- P5303 [GXOI/GZOI2019]逼死强迫症
题目地址:P5303 [GXOI/GZOI2019]逼死强迫症 这里是官方题解 初步分析 从题目和数据范围很容易看出来这是一个递推 + 矩阵快速幂,那么主要问题在于递推的过程. 满足条件的答案一定是以 ...
- P5302 [GXOI/GZOI2019]特技飞行
题目地址:P5302 [GXOI/GZOI2019]特技飞行 这里是官方题解(by lydrainbowcat) 题意 给 \(10^5\) 条直线,给 \(x = st\) 和 \(x = ed\) ...
- P5301 [GXOI/GZOI2019]宝牌一大堆
题目地址:P5301 [GXOI/GZOI2019]宝牌一大堆 这里是官方题解(by lydrainbowcat) 部分分 直接搜索可以得到暴力分,因为所有和牌方案一共只有一千万左右,稍微优化一下数据 ...
随机推荐
- python基础杂记
一.编码 1.ACSII 0000 0001 8位 一个字节 2. uncoide ...
- 随心测试_数据库_001<论数据的重要性>
测试工作中,数据的重要性 软测工程师:作为综合运用多学科知识,保障软件质量的重要岗位.需要我们学以致用,在工作中不断学习提升.以下:软测人员必备_数据库核心技能学习点,供大家学习参考. Q1:什么是: ...
- VMware Tools 继续运行脚本未能在虚拟机中成功运行。
安装VMware Tools之后,Ubuntu弹出以下警告 sudo apt-get autoremove open-vm-tools 也可以执行这个命令(如果vmware-uninstall-too ...
- jexus上部署nuget私服vs访问403错误解决方式
因为vs去访问nuget项目的时候是以下面的方式去访问的 http://域名/nuget/Search()?$filter=IsLatestVersion&searchTerm=''& ...
- [蓝桥杯]2016蓝桥省赛B组题目及详解
/*——————————————————————————————————————————————————————————— [结果填空题]T1 (分值:3) 题目:煤球数目 有一堆煤球,堆成三角棱锥形 ...
- 龙光集团地产跃居“中国房地产500强TOP28”
3月20日,由中国房地产业协会.上海易居房地产研究院中国房地产测评中心联合主办的2019中国房地产500强测评成果发布会在北京成功举办.本次测评成果显示,龙光集团地产凭借综合实力,不仅成功跻身“中国房 ...
- Microsoft Connect 2018 Summary
https://www.microsoft.com/en-us/connectevent/
- js 替换所有指定的字符串
js 的replace方法只替换第一个匹配到的的字符 如果要全局替换,使用以下方法(g为全局标志) str.replace(/需要替换的字符串/g,"新字符串") //如果有特殊符 ...
- CBV源码分析
1 在views中写一个类,继承View,里面写get方法,post方法 2 在路由中配置: url(r'^test/', views.Test.as_view()),实际上第二个参数位置,放的还是一 ...
- [洛谷P1006] 传纸条
双线程DP的常识:DP的阶段问题:多阶段决策问题 传送门:$>here<$ 题意 n*m的矩阵里,从左上角走到右下角(只能往右或往下),再从右下角走回左上角(只能往左或往上).其中不能重复 ...