折线统计

题目链接: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. 单线程的as-if-serial语义

    单线程的as-if-serial语义 关于指令重排序有个问题不明白的一个问题 int a = 2; int c = 1 + a; float b = 3f / 2f; 举个栗子,从CPU的设计者以及编 ...

  2. PAT练习num1-害死人补偿命的3n+1猜想

    卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 ( 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 年的世界 ...

  3. UI测试框架

    1. 从上到下共分成4层: 用例层  组件管理层  元素管理层  公共数据层 2. 用例层: 将每条用例使用参数化, 公共参数存储到"公共数据层", 中间参数通过组件层传递 3. ...

  4. django之orm单表查询

    这几天重新学习了一下django的orm,以此作为记录来分享. Part1:修改配置,生成表 在写数据和查数据之前,首先先得把django配置一下,具体配置如下: 1.先在公共项目的settings中 ...

  5. Databricks 第10篇:Job

    Job是立即运行或按计划运行notebook或JAR的一种方法,运行notebook的另一种方法是在Notebook UI中以交互方式运行. 一,使用UI来创建Job 点击"Jobs&quo ...

  6. Scrapy——將數據保存到MySQL數據庫

    Scrapy--將數據保存到MySQL數據庫 1. 在MySQL中創建數據庫表job_inf: 1 Create table job_inf( 2 id int(11) not null auto_i ...

  7. argparse的简单使用

    简单记录一下argparse的用法 这个是针对我做区块链的一些demo时需要用到的,仅把用到了的一些操作记录,argparse很强大,更多细致的操作可以参考:https://docs.python.o ...

  8. 页面切换提速30%!京东商城APP首屏耗时监控及优化实践

    https://mp.weixin.qq.com/s/vIG_x1MWC33HKV1GxalVHg 原创 平台研发朱跃棕等 京东零售技术 2020-12-09 网络接口请求可以从接口结构合理性及多接口 ...

  9. 就是通过事件方法,在window.loaction.href里追加了参数字符串

    参考博文:https://www.kancloud.cn/digest/yvettelau/137669

  10. 一致性哈希算法C#实现

    一致性hash实现,以下实现没有考虑多线程情况,也就是没有加锁,需要的可以自行加上.因为换行的问题,阅读不太方便,可以拷贝到本地再读. 1 /// <summary> 2 /// 一致性哈 ...