考虑 \(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. Sentinel :微服务哨兵

    1. Sentinel 是什么? 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性. Sentin ...

  2. Promise里的代码为什么比setTimeout先执行

    当浏览器或者Node拿到一段代码时首先做的就是传递给JavaScript引擎,并且要求它去执行. 然而,执行 JavaScript 并非一锤子买卖,宿主环境当遇到一些事件时,会继续把一段代码传递给 J ...

  3. 【移动测试】你的测试用例中,是否包含App前后台切换

    App前后台切换是我们平时常用的一个操作,比如:按手机的home键将应用置于后台.直接按手机电源键关闭屏幕或者通过最近打开的应用列表切换应用等,由此,我们可以得出结论:当app置于前台时,它的页面对我 ...

  4. php5升php7代码修改整理

    1. 为什么升级至php7 a.安全需要 过早以至于不维护的php版本难免会有未修补的漏洞,安全性要求较高的行业是要及时升级的. b.性能提升(开启opcache hugepage) 据说性能提升一倍 ...

  5. 唬人的Java泛型并不难

    泛型 public interface Foo<E> {}public interface Bar<T> {}public interface Zar<?> {} ...

  6. python认识及环境变量

    什么是python? python是一种脚本语言,是高级语言.计算机只能识别机器语言,在机器语言上是汇编语言,再往上是高级语言.高级语言的基础是C语言. python语言较为简单,易入门. pytho ...

  7. 【新书推荐】《ASP.NET Core微服务实战:在云环境中开发、测试和部署跨平台服务》 带你走近微服务开发

    <ASP.NET Core 微服务实战>译者序:https://blog.jijiechen.com/post/aspnetcore-microservices-preface-by-tr ...

  8. 04-String

    动手动脑 请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? s0,s1,s2字符串的内容相同,实际占用的是同一空间,引用的是同一个对象,所 ...

  9. Windows下安装Hadoop、Spark和HBase

    1.Hadoop 安装Hadoop:下载hadoop-2.7.1.tar.gz,并解压到你想要的目录下,我放在D:\Library\hadoop-2.7.1. 配置Hadoop环境变量:HADOOP_ ...

  10. selenium,统计某分支下有多少个同类子分支的方法(用于循环获取同类型子分支属性值)

    利用selenium自动化统计微博阅读数 查看微博阅读数的元素路径 微博列表中第一条微博的元素路径“//*[@id="Pl_Official_MyProfileFeed__20"] ...