【BZOJ2253】纸箱堆叠 [CDQ分治]
纸箱堆叠
Time Limit: 30 Sec Memory Limit: 256 MB
[Submit][Status][Discuss]
Description
P 工厂是一个生产纸箱的工厂。
纸箱生产线在人工输入三个参数 n p a , 之后即可自动化生产三边边长为
(a mod P,a^2 mod p,a^3 mod P)
(a^4 mod p,a^5 mod p,a^6 mod P)
....
(a^(3n-2) mod p,a^(3n-1) mod p,a^(3n) mod p)
的n个纸箱。
在运输这些纸箱时,为了节约空间,必须将它们嵌套堆叠起来。
一个纸箱可以嵌套堆叠进另一个纸箱当且仅当它的最短边、次短边和最长边长度分别严格小于另一个纸箱的最短边、次短边和最长边长度。
你的任务是找出这n个纸箱中数量最多的一个子集,使得它们两两之间都可嵌套堆叠起来。
Input
输入文件的第一行三个整数,分别代表 a,p,n
Output
输出文件仅包含一个整数,代表数量最多的可嵌套堆叠起来的纸箱的个数。
Sample Input
Sample Output
【样例说明】
生产出的纸箱的三边长为(10, 15, 14), (4, 6, 9) , (5, 16, 7), (2, 3, 13)。
HINT
Main idea
每一个元素有三个属性a,b,c,求出最大可连续堆叠个数(可堆叠条件是a1<a2,b1<b2,c1<c2)
Solution
题目显然是三维偏序问题,运用CDQ分治求解。
用排序处理a保证a有序,分治的时候满足左区间的b都小于右区间的b,再处理c,这样问题就转化为了求一个点在一个平面上横纵坐标都小于它的点有几个,用树状数组处理即可。
发现这样处理之后答案只能满足<=该点,考虑如何令答案严格小于。
首先b,c的严格小于处理显然,因为a是sort保证的那么如何要使得a的统计严格小于呢?只需要在b的sort前将分割的指针向左移动到第一个不等于的即可,结合分治考虑一下while(q[mid].a==q[mid-1].a) mid--,发现这样处理最后会影响到排序,所以做右区间的时候重新按照a排序一下即可。
考虑如何统计答案,发现显然有: q[j].ans=max(q[j].ans,Query(q[j].c-1)+1)。
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std; const int ONE=; int n,MOD,a,m;
int PD[];
int res;
int C[ONE];
int Ans,cnt; struct power
{
int a,b,c;
int ans;
}q[ONE]; struct point
{
int pos,value;
}Lisa[ONE]; int get()
{
int res,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int cmp(const power &a,const power &b)
{
if(a.a!=b.a) return a.a<b.a;
if(a.b!=b.b) return a.b<b.b;
return a.c<b.c;
} int cdp(const power &a,const power &b)
{
if(a.b!=b.b) return a.b<b.b;
return a.c<b.c;
} int rule(const power &a,const power &b)
{
return (a.a==b.a && a.b==b.b && a.c==b.c);
} int lowbit(int x)
{
return x&-x;
} int Add(int R,int x)
{
for(int i=R;i<=cnt;i+=lowbit(i))
C[i]=max(C[i],x);
} int Query(int R)
{
res=;
for(int i=R;i>=;i-=lowbit(i))
res=max(res,C[i]);
return res;
} int Clear(int R)
{
for(int i=R;i<=cnt;i+=lowbit(i))
C[i]=;
} int clis(const point &a,const point &b)
{
return a.value<b.value;
} void GetLisan()
{
sort(q+,q+n+,cmp);
n=unique(q+,q+n+,rule)--q; for(int i=;i<=n;i++)
{
Lisa[i].pos=i;
Lisa[i].value=q[i].c;
}
sort(Lisa+,Lisa+n+,clis); cnt=;
Lisa[].value=-;
for(int i=;i<=n;i++)
{
if(Lisa[i].value!=Lisa[i-].value) cnt++;
q[Lisa[i].pos].c=cnt;
} } void Deal(int l,int r)
{
if(l>=r) return;
int mid=(l+r)/;
while(q[mid].a==q[mid-].a) mid--;
if(mid<l) return;
Deal(l,mid);
sort(q+l,q+mid+,cdp); sort(q+mid+,q+r+,cdp); int i=l,j=mid+;
while(j<=r)
{
while(i<=mid && q[i].b<q[j].b)
{
Add(q[i].c,q[i].ans);
i++;
} q[j].ans=max(q[j].ans,Query(q[j].c-)+);
j++;
} for(int T=l;T<=mid;T++)
{
Clear(q[T].c);
}
sort(q+mid+,q+r+,cmp);
Deal(mid+,r);
} int main()
{
a=get(); MOD=get(); n=get();
int j=; res=;
for(int i=;i<=n;i++)
{
for(int j=;j<=;j++)
{
res=(long long)res*a%MOD;
PD[j]=res;
}
sort(PD+,PD++);
q[i].a=PD[]; q[i].b=PD[]; q[i].c=PD[];
q[i].ans=;
} GetLisan(); Deal(,n);
for(int i=;i<=n;i++)
Ans=max(Ans,q[i].ans); printf("%d",Ans);
}
【BZOJ2253】纸箱堆叠 [CDQ分治]的更多相关文章
- 【BZOJ2253】[2010 Beijing wc]纸箱堆叠 cdq分治
[BZOJ2253][2010 Beijing wc]纸箱堆叠 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后,即可自动化生产三边边长为 ...
- BZOJ2253 2010 Beijing wc 纸箱堆叠 CDQ分治
这题之前度娘上没有CDQ分治做法,gerwYY出来以后写了一个.不过要sort3遍,常数很大. gerw说可以类似划分树的思想优化复杂度,但是蒟蒻目前不会划分树(会了主席树就懒得去弄了). 嗯 将me ...
- BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组
BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后, ...
- bzoj2253 纸箱堆叠
题目链接 题意 求三元组的严格上升子序列 思路 先考虑暴力\(dp\)一下 for(int i = 1;i <= n;++i) for(int j = 1;j < i;++j) if(x[ ...
- bzoj2253纸箱堆叠(动态规划+cdq分治套树状数组)
Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , 之后,即可自动化生产三边边长为 (a mod P,a^2 mod p,a^3 mod P) (a^4 ...
- cdq分治(偏序)
偏序问题: https://www.luogu.org/blog/Owencodeisking/post-xue-xi-bi-ji-cdq-fen-zhi-hu-zheng-ti-er-fen 优质题 ...
- BZOJ2253: [2010 Beijing wc]纸箱堆叠
题解: 其实就是求三维偏序最长链.类似于三维逆序对,我们可以用树状数组套平衡树来实现. DP方程 :f[i]=max(f[j]+1) a[j]<a[i] 我们按一维排序,另一位建立树状数组,把第 ...
- 纸箱堆叠 bzoj 2253
纸箱堆叠 (1s 128MB) box [问题描述] P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n, p, a 之后,即可自动化生产三边边长为 (a mod P, a^2 mod p ...
- 【教程】简易CDQ分治教程&学习笔记
前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦! CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...
随机推荐
- ExtJs工具篇(3)——Aptana Studio3乱码的问题
在Aptana Studio里面使用,发现输入的中文是乱码,在浏览器中浏览也是乱码,想着肯定是编码的问题,但是一直没有找到在那个地方设置.以为汉化后就可以了,没想到汉化后竟然还是乱码, ...
- runtime总结 iOS
Runtime的特性主要是消息(方法)传递,如果消息(方法)在对象中找不到,就进行转发,具体怎么实现的呢.我们从下面几个方面探寻Runtime的实现机制. Runtime介绍 Runtime消息传递 ...
- 链接程序的时候遇到问题:fatal error LNK1104: cannot open file 'rctrl-d.lib'
1.lib库文件没有添加到工程中(工程里面根本就没有这个文件) 2.
- mybatis <collection>标签 类型为string时无法获取重复数据错误
1.场景: fyq_share_house 表 和 fyq_sh_tag 表 两张表是一对多的关系, 一个楼盘对应多个标签,在实体类ShareHouse中使用 /** * 楼盘标签 */ privat ...
- 【个人训练】(UVa146)ID Codes
题意与解析 这题其实特别简单,求给定排列的后继.使用stl(next_permutation)可以方便地解决这个问题.但是,想要自己动手解就是另外一回事了.我的解法是从后往前找到第一个$a_i$比$a ...
- Linux-Qt Quick学习1-Hello world
Qt作为共平台的开发IDE.实在是强大,在Quick的学习中,与平台无关,我这里使用ubuntu和openSUSE,之所以不用Windows,是因为我想借这个机会过学习一点linux的东西,哪怕是熟悉 ...
- LR创建数据源读取excel
1 在window上创建数据源 2 创建对应的数据文件 excel 注:注意格式和底部的表单名称 3 Vegen中创建参数 注意:机器数据源选择windows的ODBC数据源 SQL查的是(she ...
- 常用模块(xml)
XML(可扩展性标记语言)是一种非常常用的文件类型,主要用于存储和传输数据.在编程中,对XML的操作也非常常见. 本文根据python库文档中的xml.etree.ElementTree类来进行介绍X ...
- eclipse版本命名规则与其他软件命名
文章:Eclipse各版本代号一览表 eclipse使用星球.神话人物.元素名称作为命名代号. 所以思路要放宽,不要拘泥于已有经验. java是用咖啡命名的: python中文意思是蟒蛇: 不拘泥于已 ...
- 【转】C++操作符的优先级 及其记忆方法
优先级 操作符 描述 例子 结合性 1 ()[]->.::++-- 调节优先级的括号操作符数组下标访问操作符通过指向对象的指针访问成员的操作符通过对象本身访问成员的操作符作用域操作符后置自增操作 ...