折线统计

题目链接: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. 通过trace分析优化其如何选择执行计划

    mysql5.6提供了对sql的跟踪trace,通过trace文件能够进一步了解为什么优化其选择执行计划a而不选b执行计划,帮助我们更好的理解优化其的行为. 使用方式:首先打开trace,设置格式为j ...

  2. kubernets之持久卷的动态配置

    一  介绍持久卷的动态配置原理 前面介绍的pv以及pvc,都需要kubernets集群管理员来支持实际的底层存储,但是kubernets还支持动态配置持久卷来自动化完成这个任务集群管理员可以创建一个持 ...

  3. os-Bytes环境变量劫持

    信息收集 netdiscovery -i eth0 nmap -sV -sC 192.168.43.74 -oA os-Bytes gobuster -u 192.168.43.74 -w /usr/ ...

  4. CWE 4.3:强化你的数据自我保护能力

    摘要:如何通过软件自动的检查法规中涉及的数据保护, 新版的CWE 4.3 给出了一个解决途径. 1. 按照惯例,先说故事 用12月初在深圳参加的"全球C++及系统软件技术大会"里C ...

  5. 原生ajax分享

    最近被大佬问了一个很有趣的问题,你还能手打出一个ajax吗?,我当时的想法是有现成的为什么要自己打,后来我反思了一下(只有靠自己才是强者),在这里给大家分享一个我自己打的ajax,也是自己的一个知识点 ...

  6. Atlas 2.1.0 实践(3)—— Atlas集成HIve

    Atlas集成Hive 在安装好Atlas以后,如果想要使用起来,还要让Atlas与其他组件建立联系. 其中最常用的就是Hive. 通过Atlas的架构,只要配置好Hive Hook ,那么每次Hiv ...

  7. /bin/sh: cc: command not found

    make的时候报错:/bin/sh: cc: command not found 解决: 1. sudo yum -y install gcc gcc-c++ libstdc++-devel 2. m ...

  8. 网易新闻App架构重构实践:DDD正走向流行

    网易新闻App架构重构实践:DDD正走向流行 https://mp.weixin.qq.com/s/FdwrT_xn3CQqpWoRVBttvQ 小智 InfoQ 2020-05-14 作者 | 小智 ...

  9. GDB查看内存命令(x命令) 用gdb查看指定地址的内存内容

    GDB查看内存命令(x命令) - super119 - 博客园 https://www.cnblogs.com/super119/archive/2011/11/18/2254382.html 可以使 ...

  10. mysql查询数据库中是否存在某个字段

    select table_name from information_schema.columns where table_schema = '库名' and column_name='字段名';