折线统计

题目链接:ybt金牌导航1-2-3

题目大意

在一个图上有一些点,保证任意两个点的横纵坐标都不相同。

要你选一些集合,按 x 坐标排序依次连接,会构成一些连续上升下降的折线,问你折线数量是 k 条的有多少个集合满足。

数量对 100007 取模。

思路

这道题我们考虑先看普通的 dp 怎么弄。

因为是按 \(x\) 坐标依次连边,那我们先把点按 \(x\) 坐标从小到大排序。那如果你在这里选一个集合,那在这里相连的就要连边。

那我们设 \(f_{i,j,k}\) 为前 \(i\) 个点在一定选 \(i\) 号点中选到形成了 \(j\) 段,然后最后一段的状态时 \(k\)。(\(k\) 只有上升 \(0\) 和下降 \(1\) 两个值)

很容易想到转移方程是先分上升下降,然后要么跟原来最后一段状态一样,要么不一样。

我们先以变成上升,就是转移后 \(k=0\) 的情况。

那如果不变,那就是段数不变,第一维要枚举 \(1\) 到 \(i-1\),\(k\) 还是 \(0\)。

那如果改变,那就是段数增加了,原来的就要 \(-1\),第一维还是枚举 \(1\sim i-1\),那原来的 \(k\) 就变成了 \(1\)。

那变成下降,也是同一个道理。

但是第一维就不是枚举 \(1\sim i-1\),而是 \(i+1\sim 100000\),因为你是从高变低。

至于初始化,就是 \(f_{i,0,0}=f_{i,0,1}=1\)。

但是你这样枚举会超时。

那我们考虑用一些数据结构优化它。

这个要求区间和,还有单点更新值,很容易就想到用树状数组。

那枚举 \(1\sim i-1\) 就是直接查询 \(i-1\) 的位置,\(i+1\sim 100000\),就用查询 \(100000\) 得出的值减去查询 \(i\) 的得出的值。(就是前缀和的思想)

然后基本上就可以了,记得取模。

代码

#include<cstdio>
#include<algorithm>
#define mo 100007
#define ll long long using namespace std; struct node {
int x, y;
}zb[100001];
int n, k;
ll f[50001][11][2], tree[100001][11][2], re, ans; bool cmp(node X, node Y) {
return X.x < Y.x;
} void add(int now, int j, int k, ll add_num) {//树状数组操作
for (int i = now; i <= 100000; i += i & (-i))
tree[i][j][k] = (tree[i][j][k] + add_num) % mo;
} ll get(int now, int j, int k) {
re = 0;
for (int i = now; i; i -= i & (-i))
re = (re + tree[i][j][k]) % mo;
return re;
} int main() {
scanf("%d %d", &n, &k); for (int i = 1; i <= n; i++) {
scanf("%d %d", &zb[i].x, &zb[i].y);
} sort(zb + 1, zb + n + 1, cmp);//按 x 坐标排序 f[0][0][0] = 1;
f[0][0][1] = 1;
for (int i = 1; i <= n; i++) {
f[i][0][0] = 1;
f[i][0][1] = 1; add(zb[i].y, 0, 0, 1);
add(zb[i].y, 0, 1, 1);//初始化 for (int j = 1; j <= k; j++) {
f[i][j][0] = (get(zb[i].y - 1, j, 0) + get(zb[i].y - 1, j - 1, 1)) % mo;
//可以是跟前面一样上升,也可以变换,成为新的一段
f[i][j][1] = ((get(100000, j, 1) - get(zb[i].y, j, 1) + get(100000, j - 1, 0) - get(zb[i].y, j - 1, 0)) % mo + mo) % mo;
//同理,可以跟前面一样下降,也可以变换,由原来的上升变成下降
//不过因为你是要下降,那你就要用全部减去上升的,才可以得到下降的
//树状数组搞的是上升的,那如果你找 100000,就是最大值的话,就所有都找了一遍,就是全部的了
//或者说这就是前缀和的思想 add(zb[i].y, j, 0, f[i][j][0]);
add(zb[i].y, j, 1, f[i][j][1]);
//放进树状数组里面
} ans = (ans + f[i][k][0]) % mo;//统计答案
ans = (ans + f[i][k][1]) % mo;
} printf("%lld", ans); return 0;
}

【ybt金牌导航1-2-3】折线统计的更多相关文章

  1. 【ybt金牌导航1-2-6】【luogu P2467】地精部落

    地精部落 题目链接:ybt金牌导航1-2-6 / luogu P2467 题目大意 有一个排列,要使得每个位置要么都比两边高,要么比两边低. 而且一定要以一高一低的方式排列. 两边的只用比旁边的那个高 ...

  2. 【ybt金牌导航1-2-5】【luogu P3287】优美玉米 / 方伯伯的玉米田

    优美玉米 / 方伯伯的玉米田 题目链接:ybt金牌导航1-2-5 / luogu P3287 题目大意 有一个数组,你可以每次给一个区间里面的值加一,要你使得最后剩下的最长单调不下降子序列最长. 思路 ...

  3. 【ybt金牌导航1-2-4】免费馅饼

    免费馅饼 题目链接:ybt金牌导航1-2-4 题目大意 有一个直线,在某一个时刻有一个馅饼会出现在一些位置,有它的价值. 一个人一开始可以站在直线的任意地方,然后他每个时刻可以不移动,或向任意一边移动 ...

  4. BZOJ3688: 折线统计

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

  5. 折线统计(line)

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

  6. [FJSC2014]折线统计

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

  7. [BZOJ2688]折线统计

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

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

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

  9. 题解 bzoj3688【折线统计】

    考虑 \(dp\) . 首先把所有节点按 \(x\) 从小到大排序是很有必要的. 记 f[i][j][0] 表示满足以第 \(i\) 个节点做折线结尾,选取的点集 \(S\) 满足 \(f(S)=j\ ...

随机推荐

  1. 【Spring】创建一个Spring的入门程序

    3.创建一个Spring的入门程序 简单记录 - Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)- Spring的基本应用 Spring与Spring MVC的 ...

  2. npm i 报错 'match' of undefined 错误以及删除node_modules失败

    简单粗暴的解决办法就是一个字'删', 1.先把node_modules给删了 手动删除的话,window系统经常会有部分删不了,说需要个权限什么的,直接用rimraf 就能解决 先安装npm inst ...

  3. JVM(七)字符串详解

     常量池: 我们前面也一直说常量池有三种: 1:class文件中的常量池,前面我们解析class文件的时候解析的就是,这是静态常量池.在硬盘上. 2:运行时常量池.可以通过HSDB查看,是Instan ...

  4. spring源码分析之玩转ioc:bean初始化和依赖注入(一)

    最近赶项目,天天加班到十一二点,终于把文档和代码都整完了,接上继续整. 上一篇聊了beanProcess的注册以及对bean的自定义修改和添加,也标志着创建bean的准备工作都做好了,接下来就是开大招 ...

  5. 回滚原理 Since database connections are thread-local, this is thread-safe.

    mysql django 实践: django @transaction.atomic 机制分析  1.数据库清空表Tab 2.请求django-view        @transaction.at ...

  6. Springboot中mybatis控制台打印sql语句

    Springboot中mybatis控制台打印sql语句 https://www.jianshu.com/p/3cfe5f6e9174 https://www.jianshu.com/go-wild? ...

  7. DPDK CAS(compare and set)操作

    前言 rte_ring是一个无锁队列,无锁队列的出队入队操作是rte_ring实现的关键.因此,本文主要讲解dpdk是怎样使用无锁机制实现rte_ring的多生产者入队操作. rte_atomic32 ...

  8. 切片声明 切片在内存中的组织方式 reslice

    数组是具有相同 唯一类型 的一组已编号且长度固定的数据项序列(这是一种同构的数据结构),[5]int和[10]int是属于不同类型的.数组的编译时值初始化是按照数组顺序完成的(如下). 切片声明方式, ...

  9. WebServices 与 Web API 的区别

    WebServices : WebServices 是可以通过 Internet 访问并通过 XML 编码规范其通信的任何服务. 客户通过发送请求(大部分是 XML消息)来召唤 WebServices ...

  10. Webpack4.0各个击破(7)plugin篇

    目录 一. plugin概述 1.1 Plugin的作用 1.2 Compiler 1.3 Compilation 二. 如何写一个plugin 四. 实战 [参考] 一. plugin概述 1.1 ...