[bzoj3939_Usaco2015 Feb]Cow Hopscotch(线段树维护DP)
今天晚上,想到自己的线段树专题中的题还未码完。
此时,我看了看手边安详的作业,痛下决心,晚上熬夜补吧(唉~ 竞赛生的艰难啊 ~)。
于是,便有了我今日的博客。
洛谷题面 bzoj3939 Cow Hopscotch
以上链接便是相应的题目;
拿到这道题,我们可以分析一下题目性质。
对于点(x,y)点(x,y)点(x,y)来说,能跳到它上面的点的集合为:
∑i=1x−1∑j=1y−1(i,j)(a[i][j]!=a[x][y],a数组代表编号)\sum\limits^{x-1}_{i=1}\sum\limits^{y-1}_{j=1}(i,j)(a[i][j]!=a[x][y],a数组代表编号)i=1∑x−1j=1∑y−1(i,j)(a[i][j]!=a[x][y],a数组代表编号)。
遇到这种在二维数组内求解方案数的题目,我们会很自然而然地想到区间DP,更何况n,m的数值还比较小。最暴力的方法,便是四重循环,在外面两层枚举行与列,在内两层枚举1~ x-1, 1 ~ y-1。然后,将符合条件的f[i][j]赋值到f[x][y]上。
但是,n4n^4n4的时间复杂度,肯定会爆。(但据说数据太水了,n4n^4n4的算法都可以过。)
那么,我们就需要线段树这种数据结构来维护了。
根据二维前缀和思想,我们可以再开一个数组sum,记录f(也就是DP数组)的前缀和。
那么,对于当前的f[x][y]f[x][y]f[x][y],我们可以用sum[x−1][y−1]sum[x-1][y-1]sum[x−1][y−1]减去∑i=1x−1∑j=1y−1f(i,j)\sum\limits^{x-1}_{i=1}\sum\limits^{y-1}_{j=1}f(i,j)i=1∑x−1j=1∑y−1f(i,j),且a[i][j]=a[x][y]a[i][j]=a[x][y]a[i][j]=a[x][y]。
前缀和的问题我们不用考虑了,剩下的就是怎么快速求:
∑i=1x−1∑j=1y−1f(i,j)(a[i][j]=a[x][y])\sum\limits^{x-1}_{i=1}\sum\limits^{y-1}_{j=1}f(i,j)(a[i][j]=a[x][y])i=1∑x−1j=1∑y−1f(i,j)(a[i][j]=a[x][y])。
思考一下,每个点的编号最大是n∗mn*mn∗m,且n,m都是比较小的常数。那么,我们可以对每个编号开一个线段树,用来记录从上到下,编号为i的点的f值。
那么,对于当前的点(x,y)(x,y)(x,y), ∑i=1x−1∑j=1y−1f(i,j)(a[i][j]=a[x][y])\sum\limits^{x-1}_{i=1}\sum\limits^{y-1}_{j=1}f(i,j)(a[i][j]=a[x][y])i=1∑x−1j=1∑y−1f(i,j)(a[i][j]=a[x][y])就可以在a[x][y]所代表的线段树中查找区间(1,y−1)(1,y-1)(1,y−1)的值(因为我们是按行开始从上往下进行处理的,所以x行以下的数就不会存进去)。
思路便是如此。
时间复杂度为:O(n∗m∗lognm)O(n*m*log nm)O(n∗m∗lognm)
代码实现如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mo=1e9+7;
const int M=1e6+10;
struct ao
{int ls,rs;int num;#define ls(x) tree[x].ls#define rs(x) tree[x].rs#define num(x) tree[x].num
}tree[M*15];
int n,m,k,a[800][800],cnt,root[600000];
ll f[800][800],sum[800][800];
void change(int &p,int l,int r,int wei,int val)
{if(!p) p=++cnt;num(p)+=val;num(p)%=mo;if(l==r) return;int mid=l+r>>1;if(wei<=mid) change(ls(p),l,mid,wei,val);else change(rs(p),mid+1,r,wei,val);
}
ll cz(int p,int l,int r,int L,int R)
{if(!p) return 0;if(l>=L&&r<=R){return num(p)%mo;}ll ans=0;int mid=l+r>>1;if(L<=mid) ans+=cz(ls(p),l,mid,L,R)%mo;if(R>mid) ans+=cz(rs(p),mid+1,r,L,R)%mo;return ans%mo;
}
int main()
{scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);}f[1][1]=sum[1][1]=1;change(root[a[1][1]],1,m,1,f[1][1]);for(int i=2;i<=n;i++)sum[i][1]=1;for(int i=2;i<=m;i++)sum[1][i]=1;for(int i=2;i<=n;i++){for(int j=2;j<=m;j++) f[i][j]=(sum[i-1][j-1]%mo-cz(root[a[i][j]],1,m,1,j-1)%mo+mo)%mo;;for(int j=2;j<=m;j++) sum[i][j]=(sum[i-1][j]%mo+sum[i][j-1]%mo+f[i][j]-sum[i-1][j-1]%mo+mo)%mo;for(int j=2;j<=m;j++) change(root[a[i][j]],1,m,j,f[i][j]);}cout<<f[n][m];return 0;
}
[bzoj3939_Usaco2015 Feb]Cow Hopscotch(线段树维护DP)相关推荐
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp
D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...
- YBTOJ:采矿战略(线段树维护dp、树链剖分)
文章目录 题目描述 解析 代码 题目描述 所谓线段树维护dp,就是在线段树上维护dp (逃) 解析 把树剖一下后就变成了区间问题 考虑建一棵线段树,每一个结点都是一个背包 这样就能区间查询,也能带修了 ...
- 【BZOJ2164】采矿 树链剖分+线段树维护DP
[BZOJ2164]采矿 Description 浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略.这个城市可以看成一棵有n个节点的有根树,我们把每个节点用1到n ...
- 兰州大学第一届 飞马杯 ★★飞马祝福语★★ 线段树维护dp(动态dp)
传送门 文章目录 题意: 思路: 题意: 给你一个串,每次将区间都修改为某一个字母,问最终包含多少个FeiMaFeiMaFeiMa子序列. 思路: 首先暴力修改肯定是不行的,复杂度nqnqnq. 如果 ...
- BZOJ 4422 Cow Confinement (线段树、DP、扫描线、差分)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4422 我真服了..这题我能调一天半,最后还是对拍拍出来的...脑子还是有病啊 题解: ...
- 【BZOJ-4422】Cow Confinement 线段树 + 扫描线 + 差分 (优化DP)
4422: [Cerc2015]Cow Confinement Time Limit: 50 Sec Memory Limit: 512 MB Submit: 61 Solved: 26 [Sub ...
- [动态dp]线段树维护转移矩阵
背景:czy上课讲了新知识,从未见到过,总结一下. 所谓动态dp,是在动态规划的基础上,需要维护一些修改操作的算法. 这类题目分为如下三个步骤:(都是对于常系数齐次递推问题) 1先不考虑修改,不考虑区 ...
- 【2019牛客暑期多校训练营(第二场)- E】MAZE(线段树优化dp,dp转矩阵乘法,线段树维护矩阵乘法)
题干: 链接:https://ac.nowcoder.com/acm/contest/882/E?&headNav=acm 来源:牛客网 Given a maze with N rows an ...
- Codeforces Round #603 (Div. 2) E. Editor 线段树维护括号序列
传送门 文章目录 题意: 思路: 题意: 思路: 首先一个括号序列合法的条件可以转化成两个(左括号代价为111,右括号代价为−1-1−1): (1) 左括号个数等于右括号个数. (2) 括号的前缀和非 ...
- [ZJOI2010] 基站选址(线段树优化dp)
problem luogu-P2605 solution 首先,肯定都能想到最暴力的 dpdpdp. dpi,j:idp_{i,j}:idpi,j:i 个村庄为止一共选了 jjj 个基站,且第 ii ...
最新文章
- 机器学习隐私研究新进展:数据增强风险被低估,新算法“降服”维数依赖
- 表格布局(tablelayout)
- MySQL最后一次查询耗时查询
- python从多层循环嵌套中退出_python中退出多层循环的方法
- Django配置bootstrap
- [转]最常用的15大Eclipse开发快捷键技巧
- 每天看技术文章头大,搞点笑话轻松一下吧
- 你了解node多进程吗
- ASP.NETMVC Model验证(五)
- Spring MVC深入讲解
- Android Studio3.5 JAVA调用C++源码方法总结
- JS中clientHeight、scrollHeight、offsetHeight、scrollTop、offsetTop的定义
- 【机器学习】图像预处理
- AXURE版富文本输入框(富文本编辑器)教程+下载
- 视频演示 | 功能新增 | 增强版在线LEFSe分析和可视化鉴定标志性基因或物种
- activereport subreport
- showdown ( markdown解析)
- 夏普Sharp SF-S751D 一体机驱动
- Word:外国人中文译名中间的“点”怎么输入
- 腾讯云 wafer2 上手,轻松部署小程序后端!
热门文章
- 企业管理信息系统成功实施的四个阶段
- 我的 OCM 之路|书写无悔青春,追梦永不止步
- 鸿蒙OS开发蜂鸣器播放《两只老虎》
- 【win7安装composer错误】:The quot;https://getcomposer.org/download/1.6.2/composer.phar.sigquot; file cou
- php话费充值接口,手机话费充值接口
- 数据库与开源编译器框架LLVM
- 东北大学材料成型工艺学中期末复习
- Butterfly美化
- 数据库期末复习:选择题汇总
- Python UnboundLocalError: local variable ‘str‘ referenced before assignment