考虑 \(dp\) 。

首先把所有节点按 \(x\) 从小到大排序是很有必要的。

f[i][j][0] 表示满足以第 \(i\) 个节点做折线结尾,选取的点集 \(S\) 满足 \(f(S)=j\) ,且最后一段折线指向右上 \((↗)\) 的方案数。

f[i][j][1] 表示满足以第 \(i\) 个节点做折线结尾,选取的点集 \(S\) 满足 \(f(S)=j\) ,且最后一段折线指向右下 \((↘)\) 的方案数 。

状态转移方程:(我觉得挺显然的,感性理解一下就行了

\[f[i][j][0]=\sum\limits_{i'<i \ \& \ y[i']<y[i]} f[i'][j][0]+\sum\limits_{i'<i \ \& \ y[i']<y[i]} f[i'][j-1][1]
\]

\[f[i][j][1]=\sum\limits_{i'<i \ \& \ y[i']>y[i]} f[i'][j][1] + \sum\limits_{i'<i \ \& \ y[i']>y[i]} f[i'][j-1][0]
\]

答案即为 \(\sum f[i][k][0]+\sum f[i][k][1]\) 。

然后我们发现直接这样做 \(dp\) 是 \(Θ(n^2k)\) 的。

\(...\)

其实我们可以发现:

这个 \(i'<i\) 的限制按照 \(x\) 从小到大扫描的顺序就可以解决。

这个 \(y[i']<y[i]\) 以及 \(y[i']>y[i]\) 的限制可以用一个数据结构(线段树 \(/\) 树状数组)优化成 \(\log\) 。

时间复杂度 \(Θ(n \ k \log n)\) 。


Code 部分

#include<cstdio>
#include<algorithm> #define RI register int using namespace std; inline int read()
{
int x=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-f;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
return x*f;
} const int SIZE=50010,M=21,MAXV=100000; const int mod=1e5+7; int n,m; struct Node{
int x,y;
}a[SIZE]; int cmp(Node a,Node b)
{
return a.x<b.x;
} int c[M][MAXV+100][2]; void add(int d1,int x,int d2,int val)
{
for(;x<=MAXV;x+=x&-x)c[d1][x][d2]=(c[d1][x][d2]+val)%mod;
} int ask(int d1,int d2,int x)
{
int ans=0;
for(;x;x-=x&-x)ans=(ans+c[d1][x][d2])%mod;
return ans;
} int query(int d1,int d2,int l,int r)
{
if(l>r)return 0;
int ans=ask(d1,d2,r)-ask(d1,d2,l-1);
ans+=mod;
ans%=mod;
return ans;
} int f[SIZE][M][2]; int main()
{
n=read(),m=read(); for(RI i=1;i<=n;i++)
a[i].x=read(),a[i].y=read(); sort(a+1,a+1+n,cmp); add(0,a[1].y,0,1);
add(0,a[1].y,1,1); for(RI i=2;i<=n;i++)
{
f[i][0][0]=f[i][0][1]=1;
for(RI j=1;j<=m;j++)
f[i][j][0]=(query(j,0,1,a[i].y-1)+query(j-1,1,1,a[i].y-1))%mod,
f[i][j][1]=(query(j,1,a[i].y+1,MAXV)+query(j-1,0,a[i].y+1,MAXV))%mod;
for(RI j=0;j<=m;j++)
add(j,a[i].y,0,f[i][j][0]),add(j,a[i].y,1,f[i][j][1]);
} printf("%d\n",(ask(m,0,MAXV)+ask(m,1,MAXV))%mod); return 0;
}

\[thanks \ for \ watching
\]

题解 bzoj3688【折线统计】的更多相关文章

  1. BZOJ3688: 折线统计

    题解: 令f[i][j][0/1]表示前i个数有j段,最后一段是下降/上升的方案数 很容易列出状态转移方程(已按x轴排序) f[i][j][0]=sigma(f[k][j][0]+f[k][j-1][ ...

  2. BZOJ3688 折线统计 【dp + BIT】

    题目链接 BZOJ3688 题解 将点排序 设\(f[i][j][0|1]\)表示以第\(i\)点结尾,有\(j\)段,最后一段上升或者下降的方案数 以上升为例 \[f[i][j][0] = \sum ...

  3. BZOJ3688 折线统计【树状数组优化DP】

    Description 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中,1-&g ...

  4. 2018.09.28 bzoj3688: 折线统计(dp+树状数组)

    传送门 简单树状数组优化dp. 注意到k很小提示我们搜(d)(d)(d)索(p)(p)(p). 先按第一维排序. 用f[i][j][0/1]f[i][j][0/1]f[i][j][0/1]表示第i个点 ...

  5. 折线统计(line)

    折线统计(line) 题目描述 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中, ...

  6. 【ybt金牌导航1-2-3】折线统计

    折线统计 题目链接:ybt金牌导航1-2-3 题目大意 在一个图上有一些点,保证任意两个点的横纵坐标都不相同. 要你选一些集合,按 x 坐标排序依次连接,会构成一些连续上升下降的折线,问你折线数量是 ...

  7. [FJSC2014]折线统计

    [题目描述] 二维平面上有n 个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x 坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中,1->2 ...

  8. 题解 P1308 【统计单词数】

    小金羊发一篇不一样的题解: 这个题解不是讲解法的,是讲算法的... 众所周知,string在中被定义为是类型, 这意味着我们可以将它作为int一样的类型使用. 并且还有神奇的加减法: string s ...

  9. [BZOJ2688]折线统计

    Description 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中,1-&g ...

随机推荐

  1. BitSet 的使用

    BitSet 的简单介绍 BitSet,即位图,是位操作的对象,值只有 0 或 1(即 false 或 true). Java 的 BitSet 内部维护着一个 long 数组,默认初始化时数组的长度 ...

  2. C++ | C++ 基础知识 | 指针、数组与引用

    1.指针 在 C++ 语言中存放及使用内存地址是通过指针和引用完成的. char c = 'a'; // 声明 c 变量,c 变量存储的是 'a' 的值. char* p = &c; // 声 ...

  3. C# WPF 嵌入网页版WebGL油田三维可视化监控

    0x00 楔子 最近做的一个项目,是一个油田三维可视化监控的场景编辑和监控的系统,和三维组态有些类似,不过主要用于油田上. 效果如下图所示: 首先当然是上模型,设计人员跟进. 有了相关的模型,使用我们 ...

  4. 3maven常用命令和配置依赖

    依赖: 例:spring-context.jar 依赖 spring-aop.jar... A中的某些类 需要使用B中的某些类,则称为A依赖于B 在maven项目中,如果要使用 一个当时存在的Jar或 ...

  5. Java操作Jxl实现数据交互。三部曲——《第一篇》

    Java操作Jxl实现.xsl及.xsls两种数据表格进行批量导入数据到SQL server数据库. 本文实现背景Web项目:前台用的框架是Easyui+Bootstrap结合使用,需要引入相应的Js ...

  6. CS0656 缺少编译器要求的成员“Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create”

    问题出现原因:在net core使用动态类型dynamic,在编译的时候提示错误信息如上. 解决方案: 1.不用dynamic类型 2.在使用的地方添加一个dll,Microsoft.CSharp,或 ...

  7. DP-直线分割递推

    在 DP  里有一类是直线分割平面的问题 , 也是属于递推 类的 . 一 . 直线分割平面的问题 先考虑第一个小问题 : n 条直线最多可以将平面分割成几部分 ? 想想 最优的分割方法是怎样的呢 ? ...

  8. Jenkins 应用

    一.Jenkins Linux shell集成 新建任务 shell-freestyle-job,选择Freestyle project,点击[确定] ​ 添加描述,This is my first ...

  9. 多个github账号时,本地配置ssh-key

    由于需要,申请了多个github账号,但是都是在同一台电脑上操作,原来只有一个账号进行ssh操作时,推送没有遇到什么问题,现在有多个账号了,推送的时候就有点懵逼了,下面是根据网上的资料来进行多个账号, ...

  10. python练习题-9-6

    本代码是<Python核心编程(第二版)>第九章的9-6练习题,完成的功能为:文件比较:比较两个文本文件是否相同,如果不同,给出第一个不同处的行号和列号. #!/usr/bin/env p ...