纸箱堆叠

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

  10 17 4

Sample Output

  2
【样例说明】
  生产出的纸箱的三边长为(10, 15, 14), (4, 6, 9) , (5, 16, 7), (2, 3, 13)。
  其中只有(4, 6, 9)可堆叠进(5, 16, 7),故答案为 2。

HINT

  2<=P<=2000000000,  1<=a<=p-1, a^k mod p<>0, ap<=2000000000, 1<=N<=50000

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分治]的更多相关文章

  1. 【BZOJ2253】[2010 Beijing wc]纸箱堆叠 cdq分治

    [BZOJ2253][2010 Beijing wc]纸箱堆叠 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后,即可自动化生产三边边长为 ...

  2. BZOJ2253 2010 Beijing wc 纸箱堆叠 CDQ分治

    这题之前度娘上没有CDQ分治做法,gerwYY出来以后写了一个.不过要sort3遍,常数很大. gerw说可以类似划分树的思想优化复杂度,但是蒟蒻目前不会划分树(会了主席树就懒得去弄了). 嗯 将me ...

  3. BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组

    BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后, ...

  4. bzoj2253 纸箱堆叠

    题目链接 题意 求三元组的严格上升子序列 思路 先考虑暴力\(dp\)一下 for(int i = 1;i <= n;++i) for(int j = 1;j < i;++j) if(x[ ...

  5. bzoj2253纸箱堆叠(动态规划+cdq分治套树状数组)

    Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , 之后,即可自动化生产三边边长为 (a mod P,a^2 mod p,a^3 mod P) (a^4 ...

  6. cdq分治(偏序)

    偏序问题: https://www.luogu.org/blog/Owencodeisking/post-xue-xi-bi-ji-cdq-fen-zhi-hu-zheng-ti-er-fen 优质题 ...

  7. BZOJ2253: [2010 Beijing wc]纸箱堆叠

    题解: 其实就是求三维偏序最长链.类似于三维逆序对,我们可以用树状数组套平衡树来实现. DP方程 :f[i]=max(f[j]+1) a[j]<a[i] 我们按一维排序,另一位建立树状数组,把第 ...

  8. 纸箱堆叠 bzoj 2253

    纸箱堆叠 (1s 128MB) box [问题描述] P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n, p, a 之后,即可自动化生产三边边长为 (a mod P, a^2 mod p ...

  9. 【教程】简易CDQ分治教程&学习笔记

    前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦!       CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...

随机推荐

  1. RTL8195AM开发板使用

    1. 本次使用RTL8195AM测试一下,原厂资源地址:https://os.mbed.com/platforms/Realtek-RTL8195AM/ 2. 由于板子支持mbed,所以把CON2连接 ...

  2. nginx location优先级

    目录 1. 配置语法 2. 配置实例 3. 总结: 网上查了下location的优先级规则,但是很多资料都说的模棱两可,自己动手实地配置了下,下面总结如下. 1. 配置语法 1> 精确匹配 lo ...

  3. mybatis if标签比较字符串

    项目中需要在mybatis后台比较字符串 因为mybatis映射文件使用的是ognl表达式,所以不能使用 <if test="type == '0'"> 解决: < ...

  4. 「暑期训练」「Brute Force」 Restoring Painting (CFR353D2B)

    题意 给定一定条件,问符合的矩阵有几种. 分析 见了鬼了,这破题谁加的brute force的标签,素质极差.因为范围是1e5,那你平方(枚举算法)的复杂度必然爆. 然后你就会思考其中奥妙无穷的数学规 ...

  5. NOI中“大整数加法”问题不能AC的解决建议

    一.检查输入000和00相加是否出结果. 二.数组不要开小了,亲测256的数组不够.推荐1024.   附录AC程序: 如果不能AC请将256改为1024,255改为1023. #include &l ...

  6. IDEA + Maven + SSM 框架整合步骤

    因为前段时间自己想写个SSM的demo,然而不知怎么回事,配置完之后出现错误,怎么都调不好.最后从朋友那里拷了一个SSM的demo过来搭建成功,写这篇东西也是为了以后如果还有需要可以方便的查阅,并且也 ...

  7. ThinkPHP5作业管理系统中处理学生未交作业与已交作业信息

    在作业管理系统中,学生登陆到个人中心后可以通过左侧的菜单查看自己已经提交的作业和未提交作业.那么在系统中如何实现这些数据的查询的呢?首先我们需要弄清楚学生(Student).班级(class).作业提 ...

  8. MyBatis实例教程--以接口的方式编程

    以接口的方式编程: 只需要修改两个地方即可, 1.mapper.xml(实体类)配置文件, 注意mapper的namespace的名字是mapper对象的完整路径名com.xiamen.mapper. ...

  9. 并查集——poj1182(带权并查集高阶)

    题目链接:食物链 题解:点击 说一声:这题关系推导值得学习.

  10. JavaSE复习(五)网络编程

    客户端:java.net.Socket 类表示.创建Socket对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信 服务端:java.net.ServerSocket 类表示.创建Ser ...