BZOJ3688折线统计 dp+线段树

Description

二 维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升、下降的折线,设其数量为f(S)。如下图 中,1->2,2->3,3->5,5->6(数字为下图中从左到右的点编号),将折线分为了4部分,每部分连续上升、下降。
 
现给定k,求满足f(S) = k的S集合个数。

Input

第一行两个整数n和k,以下n行每行两个数(xi, yi)表示第i个点的坐标。所有点的坐标值都在[1, 100000]内,且不存在两个点,x坐标值相等或y坐标值相等

Output

输出满足要求的方案总数 mod 100007的结果

Sample Input

5 1
5 5
3 2
4 4
2 3
1 1

Sample Output

19

HINT

对于100%的数据,n <= 50000,0 < k <= 10

题解:

三维dp,dp[i][j][0]表示i个点,j个折线,最后状态为上升,dp[i][j][1]表示i个点,j个折线,最后状态为下降。用线段树或树状数组维护前缀和优化logn。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 using namespace std;
 6 const int MAXN=100001;
 7 const int mod=100007;
 8 struct Point
 9 {
10     int x,y;
11 }p[MAXN];
12 bool cmp(Point x,Point y)
13 {
14     return  x.x<y.x;
15 }
16 int dp[MAXN][11][2],pre[MAXN][11][2];
17 int lowbit(int x)
18 {
19     return (x&(-x));
20 }
21 void add(int x,int y,int k,int tar)
22 {
23     int i;
24     for(i=x;i<MAXN;i+=lowbit(i))
25     pre[i][y][k]=(pre[i][y][k]+tar)%mod;
26 }
27 int Query(int x,int y,int k)
28 {
29     int ans=0,i;
30     for(i=x;i;i-=lowbit(i))
31     ans=(ans+pre[i][y][k])%mod;
32     return ans;
33 }
34 int main(int argc, char *argv[])
35 {
36     int n,m,i,j,k,tot=0;
37     scanf("%d%d",&n,&k);
38     for(i=1;i<=n;i++)
39     scanf("%d%d",&p[i].x,&p[i].y);
40     sort(p+1,p+n+1,cmp);
41     for(i=1;i<=n;i++)
42     {
43         dp[i][0][0]=dp[i][0][1]=1;
44         add(p[i].y,0,0,1),add(p[i].y,0,1,1);
45         for(j=1;j<=k;j++) {
46             dp[i][j][0]=(dp[i][j][0]+Query(p[i].y-1,j,0)+Query(p[i].y-1,j-1,1))%mod;
47             dp[i][j][1]=(dp[i][j][1]+Query(MAXN-1,j,1)-Query(p[i].y,j,1)+Query(MAXN-1,j-1,0)-Query(p[i].y,j-1,0))%mod;
48             if(dp[i][j][1]<0) dp[i][j][1]+=mod;
49             add(p[i].y,j,0,dp[i][j][0]);
50             add(p[i].y,j,1,dp[i][j][1]);
51         }
52     }
53     for(i=1;i<=n;i++) tot=(tot+dp[i][k][0])%mod,tot=(tot+dp[i][k][1])%mod;
54     printf("%d\n",tot%mod);
55     return 0;
56 }

时间: 2024-08-25 14:49:30

BZOJ3688折线统计 dp+线段树的相关文章

题解 HDU 3698 Let the light guide us Dp + 线段树优化

http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 62768/32768 K (Java/Others) Total Submission(s): 759    Accepted Submission(s): 253 Problem Description Plain of despair was

[后缀数组+dp/AC自动机+dp+线段树] hdu 4117 GRE Words

题意: 给你N个字符串, N(1 <= N <= 2w), 所有串的长度加一起不超过30w.每个串有个值.这个值[-1000, 1000]. 问不打乱字符串顺序,从中取若干个字符串,使得前一个串是后一个串的子串,求满足前面调条件的字符串值得和最大,求这个值. 思路: 其实就是一个很明显的dp. dp[i]代表以第i个字符串结尾的最大权值. 但是就是子串这个问题怎么处理. 由于这题数据比较水可以用后缀数组处理这个问题. 将所有字符串拼接,做sa. 每次在height数组里往上和往下寻找公共前缀等

Subsequence Count 2017ccpc网络赛 1006 dp+线段树维护矩阵

Problem Description Given a binary string S[1,...,N] (i.e. a sequence of 0's and 1's), and Q queries on the string.There are two types of queries:1. Flipping the bits (i.e., changing all 1 to 0 and 0 to 1) between l and r (inclusive).2. Counting the

Codeforces 671D. Roads in Yusland(树形DP+线段树)

调了半天居然还能是线段树写错了,药丸 这题大概是类似一个树形DP的东西.设$dp[i]$为修完i这棵子树的最小代价,假设当前点为$x$,但是转移的时候我们不知道子节点到底有没有一条越过$x$的路.如果我们枚举每条路去转移,会发现这条路沿线上的其他子树的答案难以统计,那怎么办呢,我们可以让这条路向上回溯的时候顺便记录一下,于是有$val[i]$表示必修i这条路,并且修完当前子树的最小代价. 则有转移$dp[x]=min(val[j])$,且$j$这条路必须覆盖$x$. $val[i]=(\sum

题解【bzoj3688 折线统计】

考虑 \(dp\) . 首先把所有节点按 \(x\) 从小到大排序是很有必要的. 记 f[i][j][0] 表示满足以第 \(i\) 个节点做折线结尾,选取的点集 \(S\) 满足 \(f(S)=j\) ,且最后一段折线指向右上 \(()\) 的方案数. 记 f[i][j][1] 表示满足以第 \(i\) 个节点做折线结尾,选取的点集 \(S\) 满足 \(f(S)=j\) ,且最后一段折线指向右下 \(()\) 的方案数 . 状态转移方程:(我觉得挺显然的,感性理解一下就行了 \[ f[i][

HDU4719-Oh My Holy FFF(DP线段树优化)

Oh My Holy FFF Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 606    Accepted Submission(s): 141 Problem Description N soldiers from the famous "*FFF* army" is standing in a line, from le

hdu3698 Let the light guide us dp+线段树优化

http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 62768/32768 K (Java/Others) Total Submission(s): 821    Accepted Submission(s): 285 Problem Description Plain of despair was

hdu 4719 Oh My Holy FFF(dp线段树优化)

Oh My Holy FFF Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 848    Accepted Submission(s): 219 Problem Description N soldiers from the famous "*FFF* army" is standing in a line, from le

hdu5293 Tree chain problem 树形dp+线段树

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5293 在一棵树中,给出若干条链和链的权值.求选取不相交的链使得权值和最大. 比赛的时候以为是树链剖分就果断没去想,事实上是没思路. 看了题解,原来是树形dp.话说多校第一场树形dp还真多. . .. 维护d[i],表示以i为根节点的子树的最优答案. sum[i]表示i的儿子节点(仅仅能是儿子节点)的d值和. 那么答案就是d[root]. 怎样更新d值 d[i] = max(sum[i] , w[p]+s