[FJSC2014]折线统计
【题目描述】
二维平面上有n 个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x 坐标排序,顺次连接,将会构成一些连续上升、下降的折线,设其数量为f(S)。如下图中,1->2,2->3,3->5,5->6(数字为下图中从左到右的点编号),将折线分为了4 部分,每部分连续上升、下降。
aaarticlea/png;base64,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" alt="" />
现给定k,求满足f(S) = k 的S 集合个数。
【输入格式】
第一行两个整数n 和k,以下n 行每行两个数(xi, yi)表示第i 个点的坐标。
所有点的坐标值都在[1, 100000]内,且不存在两个点,x 坐标值相等或y 坐标值相等。
【输出格式】
输出满足要求的方案总数 mod 100007 的结果。
【样例输入】
5 1
5 5
3 2
4 4
2 3
1 1
【样例输出】
19
【数据范围】
对于 10% 的数据, n <= 10 , k = 1
对于 30% 的数据, n <= 1000, k = 1
对于 50% 的数据, n <= 1000, k <= 10
对于 100% 的数据, n <= 50000,0 < k <= 10
Solution
考场上mod少打一个0导致只有10分T T
10%:暴力
50%:考虑DP,记f[i][j][k]表示1~i中包含i的集合S,f(S)=j,k=0表示最后为上升趋势,k=1表示最后为下降趋势。显然有:
f[i][j][0]=Σ(f[k][j][0]+f[k][j-1][1])(k<i&&yi>yk)
f[i][j][1]=Σ(f[k][j][1]+f[k][j-1][0])(k<i&&yi<yk)
直接转移即可。
100%:注意到这个方程是在求前缀和,于是搞一颗树状数组维护一下即可。
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<algorithm>
int n,m;
struct P{int x,n;}x[],y[];
bool operator<(const P&i,const P&j){return i.x<j.x;}
int main()
{
srand(time());
freopen("line.in","w",stdout);
n=,m=;int i;
for(i=;i<=n;i++)x[i].n=y[i].n=i,x[i].x=rand(),y[i].x=rand();
std::sort(x+,x++n);std::sort(y+,y++n);
printf("%d %d\n",n,m);
for(i=;i<=n;i++)printf("%d %d\n",x[i].n,y[i].n);
}
Data Maker
#include<cstdio>
#include<algorithm>
#include<cstring>
struct P{int x,y;}a[],tmp[];int n,k,ans[];
bool operator<(const P&i,const P&j){return i.x<j.x||(i.x==j.x&&i.y<j.y);}
void work(int x)
{
int i,f=,t=,fl;
for(i=;x;x>>=,i++)
if(x&)tmp[++t]=a[i];if(t<=)return;
if(tmp[].y<tmp[].y)fl=;else fl=;
for(i=;i<t;i++)
{
if(fl==){if(tmp[i+].y<tmp[i].y)f++,fl=;}
else if(tmp[i].y<tmp[i+].y)f++,fl=;
}
ans[f]++;ans[f]%=;
}
int main()
{
scanf("%d%d",&n,&k);int i,j,d=<<n;
for(i=;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
std::sort(a+,a++n);
for(i=;i<d;i++)work(i);printf("%d\n",ans[k]);
}
10%
#include<cstdio>
#include<cstring>
#include<algorithm>
const int mod=;
int n,m,f[][][],ans;struct P{int x,y;}a[];
bool operator<(const P&i,const P&j){return i.x<j.x||(i.x==j.x&&i.y<j.y);}
int main()
{
scanf("%d%d",&n,&m);int i,j,k,l;
for(i=;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
std::sort(a+,a++n);
for(i=;i<=n;i++)f[][i][]=f[][i][]=;
for(k=;k<=m;k++)
{
for(i=;i<=n;i++)
for(j=;j<i;j++)
{
if(a[j].y<a[i].y)f[k][i][]=(f[k][i][]+f[k][j][]+f[k-][j][])%mod;
if(a[j].y>a[i].y)f[k][i][]=(f[k][i][]+f[k][j][]+f[k-][j][])%mod;
}
}
for(i=;i<=n;i++)ans=(ans+f[m][i][]+f[m][i][])%mod;printf("%d\n",ans);
}
50%
#include<cstdio>
#include<cstring>
#include<algorithm>
const int mod=;
int n,m,f[][][],ans,maxy;struct P{int x,y;}a[];
bool operator<(const P&i,const P&j){return i.x<j.x||(i.x==j.x&&i.y<j.y);}
int z0[],z1[];
void add0(int x,int t){for(t%=mod;x<=maxy;x+=x&-x)z0[x]=(z0[x]+t)%mod;}
void add1(int x,int t){for(x=maxy-x,t%=mod;x<=maxy;x+=x&-x)z1[x]=(z1[x]+t)%mod;}
int gs0(int x){int f=;for(;x;x-=x&-x)f=(f+z0[x])%mod;return f;}
int gs1(int x){int f=;for(x=maxy-x;x;x-=x&-x)f=(f+z1[x])%mod;return f;}
int main(){
scanf("%d%d",&n,&m);int i,j,k,l;
for(i=;i<=n;i++){scanf("%d%d",&a[i].x,&a[i].y);if(a[i].y>maxy)maxy=a[i].y;}maxy++;
std::sort(a+,a++n);
for(i=;i<=n;i++)f[][i][]=f[][i][]=;
for(k=;k<=m;k++)
{
memset(z0,,sizeof(z0));
memset(z1,,sizeof(z1));
for(i=;i<n;i++)
{
add0(a[i].y,f[k][i][]+f[k-][i][]);
add1(a[i].y,f[k][i][]+f[k-][i][]);
f[k][i+][]=gs0(a[i+].y);
f[k][i+][]=gs1(a[i+].y);
}
}
for(i=;i<=n;i++)ans=(ans+f[m][i][]+f[m][i][])%mod;printf("%d\n",ans);
}
100%
[FJSC2014]折线统计的更多相关文章
- BZOJ3688: 折线统计
题解: 令f[i][j][0/1]表示前i个数有j段,最后一段是下降/上升的方案数 很容易列出状态转移方程(已按x轴排序) f[i][j][0]=sigma(f[k][j][0]+f[k][j-1][ ...
- 折线统计(line)
折线统计(line) 题目描述 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中, ...
- 【ybt金牌导航1-2-3】折线统计
折线统计 题目链接:ybt金牌导航1-2-3 题目大意 在一个图上有一些点,保证任意两个点的横纵坐标都不相同. 要你选一些集合,按 x 坐标排序依次连接,会构成一些连续上升下降的折线,问你折线数量是 ...
- [BZOJ2688]折线统计
Description 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中,1-&g ...
- BZOJ3688 折线统计【树状数组优化DP】
Description 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中,1-&g ...
- 题解 bzoj3688【折线统计】
考虑 \(dp\) . 首先把所有节点按 \(x\) 从小到大排序是很有必要的. 记 f[i][j][0] 表示满足以第 \(i\) 个节点做折线结尾,选取的点集 \(S\) 满足 \(f(S)=j\ ...
- echarts 折线统计笔记
效果案例图 需要引入的js文件可以直接去官网下载 下面是代码 <!--第一步: 引入 ECharts 文件 --> <script src="static/js/myjs/ ...
- 2018.09.28 bzoj3688: 折线统计(dp+树状数组)
传送门 简单树状数组优化dp. 注意到k很小提示我们搜(d)(d)(d)索(p)(p)(p). 先按第一维排序. 用f[i][j][0/1]f[i][j][0/1]f[i][j][0/1]表示第i个点 ...
- BZOJ3688 折线统计 【dp + BIT】
题目链接 BZOJ3688 题解 将点排序 设\(f[i][j][0|1]\)表示以第\(i\)点结尾,有\(j\)段,最后一段上升或者下降的方案数 以上升为例 \[f[i][j][0] = \sum ...
随机推荐
- 3G/4G网卡使用
整体架构: pppd call option & ----------↓---------- option脚本(设置PPP连接) ----------↓---------- chat脚本(进行 ...
- navicat 数据库管理工具快捷键
最近在使用navicat 管理数据库中,因为经常要写一些sql的,但是每次都要鼠标点击运行,感觉很不爽,于是找到navicat(以下) 快捷键(最常用的): ctrl + q 打开查询窗口 ctrl ...
- OPENQUERY
SELECT * FROM OPENQUERY(saql007,' SELECT col1,col2,col3 FROM dbname.shemaname.tablename WHERE (1=1 ...
- mysql 修改root密码多种方法
方法1: 用SET PASSWORD命令 mysql -u root mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpa ...
- Windows服务安装方法
操作系统:Win8.1 安装方法:在命令行窗口中输入:InstallUtil service.exe 出错原因:需要以管理员身份启动命令行.
- swift 赋值判断
. var name:String? = "Wing" var geting = "Hello!" if let thisname = name{ geting ...
- 【POJ1811】【miller_rabin + pollard rho + 快速乘】Prime Test
Description Given a big integer number, you are required to find out whether it's a prime number. In ...
- VC++ 17、18课
进程间通信的四种方式: 剪贴板 匿名管道 命名管道 邮槽 容器和服务器程序 容器应用程序是可以嵌入或链接对象的应用程序.word就是容器应用程序. 服务器应用程序是创建对象并且当对象呗双击时,可以被启 ...
- 及其简易的js 倒计时插件
网上虽然有很多漂亮的且很实用的倒计时插件,但是,对于需要自己定制的倒计时来讲确实一个不小的障碍.最近我们的英语在线教育产品,在线考试模块需要用到一个计时器,所以顺势开发了一个自己的及时器. http: ...
- PHP开发APP接口---返回数据的封装类
参考视频http://www.imooc.com/learn/163 <?php /** * app返回数据类 * 1.接受多维,缺少键名的数组, * 2.可由输入的format参数决定返回数据 ...