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

这题挺难的。

下面是老师给我的题解:

看这题有点像个3维的偏序问题,但并不完全是,题目要求的是最大的类似于套娃的东西。

我们先按最短边排序,然后对于一个i,只有可能是j(1<=j<i)这个纸箱可以被i包含,我们记录f[i]表示i这个箱子可以包含多少个玩具。则很显然我们可以枚举这个j(1<=j<i)如果j被i完全包含,则f[i] = max(f[i], f[j] +1),最后在f数组中取最大值就是答案。

这个DP是O(n^2)级别的,我们考虑怎么优化。

方法一:

考虑到我们在排序后未知的有2维,我们可以用树套树来实现,树套树代码短,简单无脑,但是速度非常慢,即使用最快的树状数组套线段树,最慢的点要跑到0.75ms。

方法二:

用分治来优化这个DP,还是先按x排序,然后对于一个区间L,R,记mid为区间中点,我们先递归处理(L,mid),然后考虑(L,mid)对(mid+1,r)的影响,因为我们已经保证x单调递增,然后我们保证前一段区间和后一段区间的y是单调递增的,然后我们就可以用1个指针w,并枚举i(mid+1<=i<=r),我们要保证w之前的y小于i之前的y,然后每次把w往后移,同时插入z坐标,对于枚举到的i,用一个数状数组查询之前的最大值。最后递归(mid+1, r)。

我参考了dalao的博客。

传送门:http://blog.csdn.net/v5zsq/article/details/51083312

 program box(input,output);
var
a,x,y,z,f,b,c,d:array[..]of longint;
h:array[..]of longint;
m,p,n,i,j,t,l,r,mid,ans,cnt:longint;
flag:boolean;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
procedure sort0(q,h:longint);
var
i,j,c,t:longint;
begin
i:=q;j:=h;c:=x[(i+j)>>];
repeat
while x[i]<c do inc(i);
while c<x[j] do dec(j);
if i<=j then
begin
t:=x[i];x[i]:=x[j];x[j]:=t;
t:=y[i];y[i]:=y[j];y[j]:=t;
t:=z[i];z[i]:=z[j];z[j]:=t;
inc(i);dec(j);
end;
until i>j;
if j>q then sort0(q,j);
if i<h then sort0(i,h);
end;
procedure sorta(q,h:longint);
var
i,j,x,t:longint;
begin
i:=q;j:=h;x:=a[(i+j)>>];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if i<=j then
begin
t:=a[i];a[i]:=a[j];a[j]:=t;
inc(i);dec(j);
end;
until i>j;
if j>q then sorta(q,j);
if i<h then sorta(i,h);
end;
function find(x:longint):longint;
begin
l:=;r:=m;
while l<r- do
begin
mid:=(l+r)>>;
if a[mid]<x then l:=mid+ else r:=mid;
end;
if a[l]=x then exit(l) else exit(r);
end;
procedure sort(q,h:longint);
var
i,j,x,t:longint;
begin
i:=q;j:=h;x:=b[(i+j)>>];
repeat
while b[i]<x do inc(i);
while x<b[j] do dec(j);
if i<=j then
begin
t:=b[i];b[i]:=b[j];b[j]:=t;
t:=c[i];c[i]:=c[j];c[j]:=t;
t:=d[i];d[i]:=d[j];d[j]:=t;
inc(i);dec(j);
end;
until i>j;
if j>q then sort(q,j);
if i<h then sort(i,h);
end;
procedure change(k,n:longint);
begin
while k<=m do
begin
if n>a[k] then begin a[k]:=n;inc(cnt);h[cnt]:=k; end else break;
k:=k+k and (-k);
end;
end;
function ask(k:longint):longint;
var
ans:longint;
begin
ans:=;
while k> do begin ans:=max(ans,a[k]);k:=k-k and (-k); end;
exit(ans);
end;
procedure solve(l,r:longint);
var
mid:longint;
begin
if l=r then exit;
flag:=false;
for i:=l+ to r do if x[i]<>x[i-] then begin flag:=true;break; end;
if not flag then exit;
mid:=(l+r)>>;
i:=mid;j:=mid;if (r-l) mod = then inc(j);
if x[i]<>x[j] then mid:=i
else
while true do
begin
dec(i);inc(j);
if x[i]<>x[i+] then begin mid:=i;break; end;
if x[j]<>x[j-] then begin mid:=j-;break; end;
end;
solve(l,mid);
for i:=l to r do begin b[i]:=y[i];c[i]:=z[i];d[i]:=i; end;
sort(l,mid);sort(mid+,r);
i:=l;j:=mid+;cnt:=;
while true do
begin
if j>r then break;
if (i<=mid) and (b[i]<b[j]) then begin change(c[i],f[d[i]]);inc(i); end
else begin f[d[j]]:=max(f[d[j]],ask(c[j]-)+);inc(j); end;
end;
for i:= to cnt do a[h[i]]:=;
solve(mid+,r);
end;
begin
assign(input,'box.in');assign(output,'box.out');reset(input);rewrite(output);
readln(m,p,n);
j:=;
for i:= to n do
begin
j:=j*m mod p;x[i]:=j;
j:=j*m mod p;y[i]:=j;
j:=j*m mod p;z[i]:=j;
if x[i]>y[i] then begin t:=x[i];x[i]:=y[i];y[i]:=t; end;
if x[i]>z[i] then begin t:=x[i];x[i]:=z[i];z[i]:=t; end;
if y[i]>z[i] then begin t:=y[i];y[i]:=z[i];z[i]:=t; end;
end;
sort0(,n);
for i:= to n do a[i]:=z[i];
sorta(,n);
m:=;
for i:= to n do if a[i]<>a[i-] then begin inc(m);a[m]:=a[i]; end;
for i:= to n do z[i]:=find(z[i]);
for i:= to n do f[i]:=;
fillchar(a,sizeof(a),);
solve(,n);
ans:=;
for i:= to n do if f[i]>ans then ans:=f[i];
write(ans);
close(input);close(output);
end.

bzoj2253纸箱堆叠(动态规划+cdq分治套树状数组)的更多相关文章

  1. bzoj 1176 cdq分治套树状数组

    题面: 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Inp ...

  2. [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树)

    [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树) 题面 略 分析 首先把一组询问(x,y)看成二维平面上的一个点,我们想办法用数据结构维护这个二维平面(注意根据题意这 ...

  3. bzoj 4991 [Usaco2017 Feb]Why Did the Cow Cross the Road III(cdq分治,树状数组)

    题目描述 Farmer John is continuing to ponder the issue of cows crossing the road through his farm, intro ...

  4. 【BZOJ4285】使者 cdq分治+扫描线+树状数组

    [BZOJ4285]使者 Description 公元 8192 年,人类进入星际大航海时代.在不懈的努力之下,人类占领了宇宙中的 n 个行星,并在这些行星之间修建了 n - 1 条星际航道,使得任意 ...

  5. 【CJOJ2616】 【HZOI 2016】偏序 I(cdq分治,树状数组)

    传送门 CJOJ Solution 考虑这是一个四维偏序对吧. 直接cdq套在一起,然后这题有两种实现方法(树状数组的更快!) 代码实现1(cdq+cdq+cdq) /* mail: mleautom ...

  6. HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)

    Jam's problem again Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  7. BZOJ 2716 [Violet 3]天使玩偶 (CDQ分治、树状数组)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2716 怎么KD树跑得都那么快啊..我写的CDQ分治被暴虐 做四遍CDQ分治,每次求一个 ...

  8. UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  9. 【模板】cdq分治代替树状数组(单点修改,区间查询)

    #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #in ...

随机推荐

  1. 20155319 2017-2018-1《信息安全系统设计》第四周课堂测试、Makefile、myod

    20155319 2017-2018-1<信息安全系统设计>第四周课堂测试.Makefile.myod 测试2-gcc测试 1.用gcc 进行预处理,编译,汇编,链接vi输入的代码 2.生 ...

  2. WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书

    原文:WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书 最近项目中使用弹出控件Popup,发现弹出框的对齐方式在不同的系统中存在不同(Popup在win10上是 ...

  3. Mysql本地安装多实例后启动遇到的问题

    一.本文紧接上一篇[win10-MySql免安装版-安装/多实例] 在上一篇文章里,安装Mysql解压版后,复制多份到本地,实现了多实例的安装 在后续启动其它实例的时候会遇到一些问题,以下就是自己遇到 ...

  4. 【转载】从零实现3D图像引擎:(2)画2D直线不简单

    原文:从零实现3D图像引擎:(2)画2D直线不简单 1. 数学分析 1) 画直线的问题 本来我以为画直线会很容易,随便拿个直线公式,遍历X求Y画出来不就完了么,但事实并非如此.以2D直线为例,因为3D ...

  5. Mac Eclipse快捷键

    Command + O:显示大纲Command + 1:快速修复Command + D:删除当前行Command + Option + ↓:复制当前行到下一行Command + Option + ↑: ...

  6. Linux 安装Zookeeper<集群版>(使用Mac远程访问)

    阅读本文需要先阅读安装Zookeeper<准备> 一 架构细节 zookeeper集群根据投票选举的机制 选出leader和follower zookeeper集群节点建议是奇数 这里我准 ...

  7. KRKR基础篇(二)

    这里介绍一些krkr的语法规范,具体的命令含义及用法以后再叙述 一:kag语法及基本概念 KAG使用的剧本语言为KAG Script,文件扩展名为.ks 脚本内的文字除  注释,  命令 ,  段落标 ...

  8. flask_sqlalchemy介绍

    快速入门 Flask-SQLAlchemy 使用起来非常有趣,对于基本应用十分容易使用,并且对于大型项目易于扩展.有关完整的指南,请参阅 SQLAlchemy 的 API 文档. 一个最小应用 常见情 ...

  9. JAVA学习笔记--正则表达式

    正则表达式是一种强大而灵活的文本处理工具.使用正则表达式,可以让我们以编程的方式构造复杂的文本,并对输入的字符串进行搜索. 一.基础正则表达式语法(表格来自J2SE6_API) 字符 x 字符 x \ ...

  10. java之接口开发-初级篇-http和https

    http协议util address(url地址),str(数据参数) private static HttpMethod getPostJsonMethodInRequestBody(String ...