纸箱堆叠

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. cachel-control

    nodejs: res.set('Cache-Control', 'public, max-age=31557600'); express全局设置:       app.use(express.sta ...

  2. 『JavaScript』封装

    封装可以被定义为对对象的内部数据表现形式和实现细节进行隐藏.通过封装可以强制实施信息隐藏. 在JavaScript中,并没有显示的声明私有成员的关键字等.所以要想实现封装/信息隐藏就需要从另外的思路出 ...

  3. 第一篇 Postman的初级使用之设置环境快速切换生成环境与测试环境

    POSTMAN是有谷歌的开源工具,在开发调试.测试执行过程中使用频率非常广泛,本文将记录一些postman在测试中常见的一些配置和使用方法 一.基本的页面区域 略,很简单,大家都会看,再有,学习下面的 ...

  4. 常用模块(数据序列化 json、pickle、shelve)

    本节内容 前言 json模块 pickle模块 shelve模块 总结 一.前言 1. 现实需求 每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Py ...

  5. Selenium 启动无头浏览器,只有chrome 和 firefox的,没有IE

    使用无头浏览器,可以避免掉不确定的弹出框对脚本稳定性的影响,还能在脚本执行过程中省略掉了css 加载的时间. 以下是Selenium 启动无头浏览器的方法,只有chrome 和 firefox的. p ...

  6. Assetbundle1

    AssetBundle运行时加载:来自文件就用CreateFromFile(注意这种方法只能用于standalone程序)这是最快的加载方法也可以来自Memory,用CreateFromMemory( ...

  7. 为DEV C++/CodeBlock配置gdb调试遇到的问题

    DEV C++和CodeBlock都只是一个IDE,不能编译调试,需要自己配置MINGW和gdb调试 1.MINGW 在这下载mingw-get-setup.exe安装即可. https://sour ...

  8. 树莓派搭建 Hexo 博客(二)

    Hexo 一个开源的博客框架,本文记录了一下在树莓派上搭建 Hexo 博客的过程. 上一篇介绍了 Hexo 的配置,现在网站已经能在本地访问了,也能通过 hexo generate 命令生成静态界面 ...

  9. 辨析ADK&JVM&JRE&JDK&ADT

    一.SDK 英文全称:Software Development Kit 中文译名:软件开发工具包 详解: 由第三方服务商提供的实现软件产品某项功能的工具包. 为了扩展软件功能或其它方面而设计出来给开发 ...

  10. PhpStorm 配置IDE

    IDE => Xdebug => Apache(XAMPP) => Firefox + easist Xdebug 1>XAMPP停止apache服务;2>在安装目录下找 ...