BZOJ 3939 [Usaco2015 Feb]Cow Hopscotch ——线段树 CDQ分治
显然dp[i][j]=ps[i-1][j-1]-sigma(dp[k<i][l<j],a[i][j]=a[k][l])
考虑对于每一种颜色都开一颗区间线段树,但是空间不够。
所以我们可以动态开节点的权值线段树即可。
因为ij写反了调了30min。
然后发现空间的问题我们可以分治啊,按照纵坐标分治,然后处理左半边对右半边的影响即可。
然后CDQ分治即可,空间是O(nm)的,时间复杂度是O(nmlogm)的。
复杂度怎么算?主定理套用即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define md 1000000007
int sum[6000001],ls[6000001],rs[6000001],tot=0;
struct Dynamic_Segment_Tree{
int L,R,rt,X,C;
void init(){rt=0;}
int query(int x,int l,int r)
{
if (l>r) return 0;
if (!x) return 0;
int mid=l+r>>1;
if (L<=l&&r<=R) return sum[x];
if (R<=mid) return query(ls[x],l,mid);
else if (L>mid) return query(rs[x],mid+1,r);
else return (query(ls[x],l,mid)+query(rs[x],mid+1,r))%md;
}
void update(int x)
{
sum[x]=(sum[ls[x]]+sum[rs[x]])%md;
}
void modify(int &x,int l,int r)
{
if (!x) x=++tot;
int mid=l+r>>1;
if (l==r)
{
(sum[x]+=C)%=md;
return ;
}
if (X<=mid) modify(ls[x],l,mid);
else modify(rs[x],mid+1,r);
update(x);
}
}T[562501];
int dp[751][751],prs[751][751],r,c,k,a[751][751];
int main()
{
scanf("%d%d%d",&r,&c,&k);
F(i,1,r) F(j,1,c) scanf("%d",&a[i][j]);
F(i,1,k) T[i].init();
dp[1][1]=1;
F(i,1,r)
{
F(j,1,c)
{
(dp[i][j]+=prs[i-1][j-1])%=md;
T[a[i][j]].L=1;T[a[i][j]].R=j-1;
if (j>=2) (dp[i][j]=dp[i][j]-T[a[i][j]].query(T[a[i][j]].rt,1,c)+md)%=md;
prs[i][j]=(((prs[i][j-1]+prs[i-1][j])%md+dp[i][j])%md-prs[i-1][j-1]+md)%md;
}
F(j,1,c)
{
T[a[i][j]].X=j;T[a[i][j]].C=dp[i][j];
T[a[i][j]].modify(T[a[i][j]].rt,1,c);
}
}
printf("%d\n",dp[r][c]);
}
CDQ分治
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define md 1000000007
int a[751][751],n,m,k,sum[1000005],dp[751][751],ps[751];
void CDQ(int l,int r)
{
if (l==r) return;
int mid=l+r>>1;
CDQ(l,mid);
F(i,1,n-1)
{
F(j,l,mid)
{
(sum[a[i][j]]+=dp[i][j])%=md;
(ps[i]+=dp[i][j])%=md;
}
(ps[i]+=ps[i-1])%=md;
F(j,mid+1,r)
{
(dp[i+1][j]+=ps[i])%=md;
dp[i+1][j]=(dp[i+1][j]-sum[a[i+1][j]]+md)%md;
}
}
F(i,1,n)
{
ps[i]=0;
F(j,l,mid) sum[a[i][j]]=0;
}
CDQ(mid+1,r);
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
F(i,1,n) F(j,1,m) scanf("%d",&a[i][j]);
dp[1][1]=1;
CDQ(1,n);
printf("%d\n",dp[n][m]);
}
BZOJ 3939 [Usaco2015 Feb]Cow Hopscotch ——线段树 CDQ分治的更多相关文章
- 【BZOJ3939】[Usaco2015 Feb]Cow Hopscotch 动态规划+线段树
[BZOJ3939][Usaco2015 Feb]Cow Hopscotch Description Just like humans enjoy playing the game of Hopsco ...
- 【bzoj3939】[Usaco2015 Feb]Cow Hopscotch 动态开点线段树优化dp
题目描述 Just like humans enjoy playing the game of Hopscotch, Farmer John's cows have invented a varian ...
- [BZOJ 3888] [Usaco2015 Jan] Stampede 【线段树】
题目链接:BZOJ - 3888 题目分析 首先,计算出每个线段在 x 坐标 0 处出现的时间开始点和结束点,就转成了时间轴上的线段. 然后就是看每条线段是否被 y 比它小的线段完全覆盖了.注意求出的 ...
- BZOJ 1593: [Usaco2008 Feb]Hotel 旅馆 [线段树]
传送门 题意: 操作1:找长为$len$的空区间并填满,没有输出$0$ 操作2:将$[l,r]$之间的区间置空 我真是太弱了这种线段树还写了一个半小时,中间为了查错手动模拟了$30min$线段树操作, ...
- BZOJ 4025: 二分图 [线段树CDQ分治 并查集]
4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...
- COGS 577 蝗灾 线段树+CDQ分治
第一次写cdq分治 感谢hhd<y 这20亿对CP的指导(逃) 其实 就是 递归看左半部分对右半部分的贡献 (树状数组写挂了--临时改的线段树[大写的尴尬]) //By SiriusRen ...
- BZOJ3939 : [Usaco2015 Feb]Cow Hopscotch
设f[i][j]表示到(i,j)的方案数,则有 $f[i][j]=\sum f[x][y](x<i,y<j,a[x][y]!=a[i][j])=\sum f[x][y](x<i,y& ...
- BZOJ 4411: [Usaco2016 Feb]Load balancing 线段树+二分
code: #include <bits/stdc++.h> #define N 100060 #define M 1000000 #define lson x<<1 #def ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
随机推荐
- POJ Washing Clothes 洗衣服 (01背包,微变型)
题意:有多种颜色的衣服,由两个人合作来洗,必须洗完一种颜色才能洗下一种,求需要多少时间能洗完. 思路:将衣服按颜色分类,对每种颜色进行01背包,容量上限是该种颜色衣服全部洗完的耗时长一半,其实就是在最 ...
- spring框架的总结
http://www.cnblogs.com/wangzn/p/6138062.html 大家好,相信Java高级工程师对spring框架都很了解吧!那么我以个人的观点总结一下spring,希望大家有 ...
- pytorch中的view
https://ptorch.com/news/59.html view()相当于reshape(),其中参数若为-1表示当前的size根据其余size推断
- Hibernate 中批量处理数据
一.批量处理操作 批量处理数据是指在一个事务场景中处理大量数据.在应用程序中难以避免进行批量操作,Hibernate提供了以下方式进行批量处理数据: (1)使用HQL进行批量操作 数据库层面 ...
- 相机 感光度iso,焦距,光圈,ccd 和 噪点, 景深关系表格
表格 矩阵 感官度iso: 越低曝光速度越慢,所谓慢工出细活,成像质量会好,如果形成的话. 但是因为慢,所以要更多的光量,才能画完. 就需要更慢的快门 (但是太慢手抖的话就糊掉,或者动的物体形成轨迹. ...
- 三. python面向对象
第七章.面向对象基础 1.面向对象基础 类和对象: a. 创建类 class 类名: def 方法名(self,xxx): pass b. 创建对象 对象 = 类名() c. 通过对象执行方法 对象. ...
- 接口和类方法中的 SELF
接口和类方法中的 SELF 由 王巍 (@ONEVCAT) 发布于 2015/06/10 我们在看一些接口的定义时,可能会注意到出现了首字母大写的 Self 出现在类型的位置上: protocol I ...
- javascript基础知识 (八) BOM学习笔记
一.什么是BOM BOM(Browser Object Model)即浏览器对象模型. BOM提供了独立于内容 而与浏览器窗口进行交互的对象: 由于BOM主要用于管理窗口 ...
- HDU - 4811 - Ball (思维)
题意: 给出一定数量的三种颜色的球,计算如何摆放得到值最大(有一定顺序) 有三种摆放方法 1.如果放的是第一个(桌子上原来没有),数值不变 2.如果在末尾追加一个,那么增加前面不同颜色的个数的值 3. ...
- Centos7.2 上部署 FastDFS_V5.05
1.安装gcc (编译时需要) [root@localhost~]# yum -y install gcc gcc-c++ 2.安装libevent ,FastDFS依赖libevent库; [roo ...