【题目描述】

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

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaMAAAExCAIAAABeWVrrAAAMa0lEQVR4nO3d23naWheGUWpJGdSQOqjHrewbN+Ni2BfEsgAB04AO31pjPPvi/+PE6DDXG3GQszsCtG639gYAzE7pgPYpHdA+pQPap3RA+5QOaJ/SAe1TOqB92aXb7bK3H1hGdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVC6lvz57+/am0CzskuhdG3489/f8X9rbw4Nyi6F0jXgInNixxyyS6F0DVA6FpBdCqVLN5k5sePtskuhdA2QORaQXQqla4DSsYDsUihdG2SOuWWXQumasdvt/vz31wllJtmDZWE0YziVzilzyJ4qq6IN4/PonDKH7KmyKtpwcR6dVt4ue6QsiTYoHXPLHilLogGTJ9GZ5b2y58l6aIDSsYDseWpgPfj42K2T2MDJZTuyhyl6Mfi47PHuGYw+uWxN9jDlLga3QJ3cP4O555etyZ6k3JWgdCdKxzKyJyl0JfhRRSeV0xd6itma7DHKXQYyd1Q6FpQ9RrnLQOmO5dOXe5bZjuwZil4DF5mL3pcn1Pe3tyPDHLJnKH0NnH5U0fC/192Yhf1qf3s7OLxd9gClL4Ce7/dUOpaUPUDRC+B646N351ee2NN+Dg5zyJ6e6Onv+X5PpWNh2dOTO/2d3+z53G52cnCYQ/bo5I5+z6V7eh97ODjMJHt0Qke/81ugXtnB5g8OM8mem9C5V7pV/iw9y56bxLl/uM2JO1X3+t61fXyYSfbQJA595zd7Kh2ryB6auKHv/E7Pd+1Xq8eH+WRPTNzEd36zp9KxluyJyZp49z+9caeaPD7MJ3tcssa989K9d4/aOz7MKntcgsbd/U9v353Gjg+zyp6VlFl389NR6VhV9qykzLrSzbQvLR0iZpU9KBGD7paAo9KxtuxBiRh0pTvOuSPNHCJmlT0l259ytwQcZ96FBo4PC8ieku1PudId59+FBg4Rc8sekY2P+Fs2b+P7WKF0rC57RDY+4m5+Oi618dGHiAVkz8eW59udTydKxxZkz8eW51vpThbb+OijxNyyh2Ozw+1+gNO/2L3kZscdIpaUPRybHe6eS/fnv7/j/5Z86KCjxMKyJ2Obk93z/QAXmVs4dhGHiFVkT8Y2J1vpXNaxNdljscGx7vm2p8nMuaxjC7LHYoNj3fmdT6tf0x0TjhLLy56Jrc20mwGUjm3KnomtzbTSHVd973UQcaBYUvZAbGqg3Qyw2+2GzVurccOWrPjobFD2QGxqoHsu3bhxG7G17WFd2dOwnWnu9maADTbuZJtbxVqyp2Ej07zwZmxnrzeyJbdsfPNYUvYobGSUeyvd9ht3ErGRLCN7FLYwyqtsw1o7ntK4QdbWMp/sOdjCHPdQut23JR/0LRK3mTlkz8Hqc7zitdViD7T6QX5R+vbzFtlDsPoQr7gBC3xKefXD+xZt7AUvyh6CdYe41UdvpnGDxnaHJ2RPQKutWWsD2mvcSZM7xa9kT0DDTx4X3oZWGzdoe+94KPv0K91bvskW9mVuPewjd2Sf/ubf+nzo6S3J/eDI07raWS5kn3ulG29J8ceH9Ba4QZ97zUn2ue/hU7v3nTam+CPhum3coPPd71n2iVe6Y+3H/GrciYPQrewTv/zgbnCp3C+dxl1wNPqUfdaV7s4/x6VxkxyTPmWf9d5+XNKkW5lbe7u2y8HpUPYpV7rjNv45rizbPI/MKvuULzmyW14eMvdbWz6bzCH7fC/5w4uWeaCn7XY7javb/gnlvbLPt9LxNOe0K9kne5lhtSSa5LR2JftkKx2vcGb7kX2mF5hUi6FhTm4/ss+00vGi4fx6P6dt2ct4gX9LYdbvz+pO71n7jE7zsley0vEin7vuRPZKnrVEMtcDpetE9mJWOl5x5+cjrL1pvFn2Yp71XwKc6TuzKTLXiez1rHS8SOk6kb2eZ+qRzHVF5nqQvaTfm6RhypWuQxrXtuwl/a4k+Vsd2qZ0XqmB9imd0kH7ei+dT1RBD3ov3dE1HXRA6ZQO2qd0x6P3XqF1SvdD46BVSge0L7sUSgdUZJdC6YCK7FIoHVCRXQqlAyqyS6F0QEV2KZQOqMguhdIBFdmlUDqgIrsUSgdUZJdC6YCK7FIoHVCRXQqlAyqyS6F0QEV2KZQOqMguhdIBFdmlUDqgIrsUSgdUZJdC6YCK7FIoHVCRXQqlAyqyS6F0QEV2KZQOqMguhdIBFdmlUDqgIrsUSgdUZJdC6YCK7FIoHVCRXQqlAyqyS6F0QEV2KZQOqMguhdIBFdmlUDqgIrsUSgdUZJdC6YCK7FIoHVCRXQqlAyqyS6F0QEV2KZQOqMguhdIBFdmlUDqgIrsUSgdUZJdC6YCK7FIoHVDxtlLsABaxZulW8dw+A73JLoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVGSXQumAiuxSKB1QkV0KpQMqskuhdEBFdimUDqjILoXSARXZpVA6oCK7FEoHVCgF0D6lA9qndED7lA5on9IB7VM6oH1KB7RP6YD2KR3QPqUD2qd0QPuUDmif0gHtUzqgfUoHtE/pgPYpHdA+pQPap3RA+5QOaJ/STfk87PYfX6XfV3H4fOOmVLfthq+P/a78Db4+9i9t/MRD7+qPDu+jdBO+PvZXdTn378tn1fk8TC3iV2Pxm9KNN/PGY34edrv9fl+szXebpvf+1zty8Qe/Pvaj7Rxv/Pfvmz6kv3nE1/6aoR1Kd+06Tud1+fl/o1+furzbf3wtVrrPw+NVPaTl81ArwBuv6b4+LvI6/oXz5h2Pn4fxV55q3dfHfrff75WOE6U7c52r/cfX49KdMjdekUNLnovFjYupm1dXlXSdXSDVCvLG0l1eno23+O6lW7XKZ04bfhlQOqZ0V0bPXUclu126z385+MnC+Lcvck33+LW7iUU/mZDHiX1iZ86vd6+P6P3r0d8fwa/RGVE6jsej0l0bLazhfxaevX5/5bIGS5Tu1KxRpC5+w7gk9540PtzcF3bm/LrtorL/jtud1xaHL02nePpqUekYKN2F8WIeolIo3fcKPHwOVzAvPHv9US3dxTPT89cPL8p72YXR15cp3cRz55+CXT/Ab95uHmdR6Rgo3bnxGrx17Xb+64fDfuIyanjn72P+0l1/cOR7iU88QZ16gW70a7M8e/232YWn9N9/S1y/9V172PPfqXQMlO7KabEfDucvmT9+9nr+atT4uuLXi634Ob3vx7kqwZ0l/vSbmS+qlW746tWT27PrtBvPXm9m2if4ULpJF5dJ1dfpbnynuS8r7n6C49HvPfd5GF6Z/N7s84/SPBuNX73ze/0y3tOfNHFNx/F4VLpJp9euDj8fPH1UuvHFxMRTyxuLrXR5dd3cG69knX9o4+YCv/ugo8KMtvvi1cinvvPddyQuSnYZqKf/slA6Bkp34fyp07/VW7pHYvznz59RPfc88t93On9a+vXT1Zsv6d9d3Q8u96bemzj7Izevrx5fLE7/bfHz5Rt/WTz/fFvpGCjdmRuL6s41XfW1tGuPbuuqfELu9wW43Y2p+Eyk7upWuRt//IHyuwxLPP2nfUr3ildep7tVjFC/3p3ipdqLP9AATpSOtTx+cvnaHf7wQ+mA9ikd0D6lA9qndED7lA5on9IB7VM6oH1KB7RP6YD2KR3QPqUD2qd0QPuUDmif0gHtUzqgfUoHtE/pgPYpHdA+pQPap3RA+5QOaN//yB8dmY+4JP0AAAAASUVORK5CYII=" 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]折线统计的更多相关文章

  1. BZOJ3688: 折线统计

    题解: 令f[i][j][0/1]表示前i个数有j段,最后一段是下降/上升的方案数 很容易列出状态转移方程(已按x轴排序) f[i][j][0]=sigma(f[k][j][0]+f[k][j-1][ ...

  2. 折线统计(line)

    折线统计(line) 题目描述 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中, ...

  3. 【ybt金牌导航1-2-3】折线统计

    折线统计 题目链接:ybt金牌导航1-2-3 题目大意 在一个图上有一些点,保证任意两个点的横纵坐标都不相同. 要你选一些集合,按 x 坐标排序依次连接,会构成一些连续上升下降的折线,问你折线数量是 ...

  4. [BZOJ2688]折线统计

    Description 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中,1-&g ...

  5. BZOJ3688 折线统计【树状数组优化DP】

    Description 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中,1-&g ...

  6. 题解 bzoj3688【折线统计】

    考虑 \(dp\) . 首先把所有节点按 \(x\) 从小到大排序是很有必要的. 记 f[i][j][0] 表示满足以第 \(i\) 个节点做折线结尾,选取的点集 \(S\) 满足 \(f(S)=j\ ...

  7. echarts 折线统计笔记

    效果案例图 需要引入的js文件可以直接去官网下载 下面是代码 <!--第一步: 引入 ECharts 文件 --> <script src="static/js/myjs/ ...

  8. 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个点 ...

  9. BZOJ3688 折线统计 【dp + BIT】

    题目链接 BZOJ3688 题解 将点排序 设\(f[i][j][0|1]\)表示以第\(i\)点结尾,有\(j\)段,最后一段上升或者下降的方案数 以上升为例 \[f[i][j][0] = \sum ...

随机推荐

  1. 使用html5兼容低版本浏览器

    因为html5 新出的一些语义化的标签,在低版本浏览器下不能识别,举个例子,比如你写了一个 header 标签中,写了一段文本,在低版本浏览器下,肯定是能看到的,但是,那是他是不认识 header标签 ...

  2. query 防止ajax重复提交

    项目用到js了,首选jquery,能用库用库,原则. 碰到重复提交的问题,禁止住才行.百度google,还是Google给力. 知乎上有个高人,总结了四种,利用Jquery .post方法返回jqXH ...

  3. 样式优先级、margin

    margin:上 左 下 右:

  4. python基础知识八

    当你的程序中出现某些 异常的 状况的时候,异常就发生了.例如,当你想要读某个文件的时候,而那个文件不存在.或者在程序运行的时候,你不小心把它删除了.上述这些情况可以使用异常来处理. 如你的程序中有一些 ...

  5. MongoDB的查询

    一.Find操作 二.分页和排序 三.游标的使用 一.Find查询 事前准备:插入如下数据 db.Students.insert([ { _id:1, name:"Zhao", a ...

  6. StarUML启动时候出现"System Error. Code:1722. RPC服务器不可用."错误的解决办法

    StarUML是用得很顺手的UML工具,但是启动时候每次都会出现"System Error. Code:1722. RPC服务器不可用."错误. 一般来说这个应该是某个Window ...

  7. UI层调用WCF服务实例(源码)

    WCF原理性的东西,暂时还没有深入研究,只是在公司的项目中使用到了,会调用,然后再多做了一些了解,现在将它抽出来了一个小实例,写了一个WCF的demo. 我写的这个WCF.Demo主要包括数据契约和服 ...

  8. jQuery实现多级手风琴树形下拉菜单(源码)

    前几天因为公司的菜单要调整,公司的UI框架是不支持的,所以就自己在网上找了一个下拉菜单,可以支持多级菜单数据的,菜单数据是从xml文件中配置后读取的,网上有许多这方面的例子感觉不是很好用,就打了个包贴 ...

  9. Jsoup解析Html教程

    Jsoup应该说是最简单快速的Html解析程序了,完善的API以及与JS类似的操作方式,为Java的Html解析带来极大的方便,结合多线程适合做一些网络数据的抓取,本文从一下几个方面介绍一下,篇幅有限 ...

  10. 一天学完UFLDL

    学习UFLDL笔记 第一节 神经网络 神经元长这样 大写W看着有点不习惯.. 激活函数, 就是上面式子中的f. 可以选 sigmoid函数(或者叫 logistic回归,对数几率函数),反正就是这样一 ...