折线统计

题目链接: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. kubernets之向外部应用暴露应用

    一  通过NodePort来暴露服务 前面已经介绍的服务的一些作用,例如将集群内部的应用暴露给集群内部的pod使用,将外部的应用通过服务暴露给内部应用使用,但是服务最大的作用不仅仅是这些 而是将集群内 ...

  2. oracle 存储过程和包的权限

    GRANT CREATE ANY PROCEDURE TO MONKEY --創建,查看,替換的權限 GRANT EXECUTE ANY PROCEDURE TO MONKEY --執行和查看的權限 ...

  3. 如果using语句中出现异常,资源会被释放掉吗?

    <CLR Via C#>第三版 P489 在using内部抛出了异常,被using的对象还是会被释放掉. Using编译时会自动生成Try Finally代码块. 同样Using只能用于实 ...

  4. JVM(七)字符串详解

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

  5. java基础-01代理类

    简单的代理类实现案例主实现类:ProxyTestimport java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;im ...

  6. 浅析Linux进程空间布局

    一.进程空间分布概述 对于一个进程,其空间分布如下图所示: 1.参数说明 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码. 初始化过的数据(Data):在程序运行初已经对变量进行初 ...

  7. WPF TabControl美化

    <Window.Resources> <!-- TabItem的样式 --> <Style TargetType="{x:Type TabItem}" ...

  8. http://golang.org/s/better-linker

    http://golang.org/s/better-linker The original linker was also simpler than it is now and its implem ...

  9. 在线配置热加载配置 go-kratos.dev 监听key

    paladin https://v1.go-kratos.dev/#/config-paladin example Service(在线配置热加载配置) # service.go type Servi ...

  10. Redis集群动态增加和删除节点

    一.添加节点 1.首先将需要添加的节点启动: 这里启动redis6383.conf和redis6393.conf两个节点 查看原有节点:           3个主节点所对应的哈希槽(hash slo ...