纸箱堆叠 bzoj 2253
纸箱堆叠
【问题描述】
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个纸箱中数量最多的一个子集,使得它们两两之间都可嵌套堆叠起来。
【输入格式】
输入文件的第一行三个整数,分别代表 a, p, n
【输出格式】
输出文件仅包含一个整数,代表数量最多的可嵌套堆叠起来的纸箱的个数。
【样例输入】
10 17 4
【样例输出】
2
【样例说明】
生产出的纸箱的三边长为(10, 15, 14), (4, 6, 9) , (5, 16, 7), (2, 3, 13)。其中只有(4, 6, 9)可堆叠进(5, 16, 7),故答案为 2。
【样例说明】
2<=P<=2000000000,1<=a<=p-1,a^k mod p<>0,ap<=2000000000,1<=N<=50000
题解:
我们设长宽高为x,y,z
CDQ分治,以x为关键词排序
接下来递归分成两区间
假设左区间已经处理完了答案
将左右区间分别以y为关键字排序
那么就保证了任何左区间的x必定小于任何右区间的x
我们用两个指针分别从左右区间顺序向后扫
将左区间的z作为位置不断加入树状数组,值为当前点的答案
由于左右区间有序,可以手动保证右区间的扫到的点的y大于所有左区间扫到的点的y
就可以用树状数组更新右区间点的值:当前点的答案等于能转移到当前点的点的答案加一的最大值,这里用上了Dp的思想
然后清空树状数组,再将左右区间合并按第一维排序,恢复原状态, 保证处理的是最初的右区间,且此区间按第一维有序
接着递归处理右区间,继续更新答案
- #include<algorithm>
- #include<iostream>
- #include<cstdlib>
- #include<cstring>
- #include<cstdio>
- #include<cmath>
- using namespace std;
- inline int Get()
- {
- int x = ;
- char c = getchar();
- while('' > c || c > '') c = getchar();
- while('' <= c && c <= '')
- {
- x = (x << ) + (x << ) + c - '';
- c = getchar();
- }
- return x;
- }
- const int me = ;
- struct box
- {
- int x, y, z, ans;
- };
- box c[me], s[me];
- int a, p, n, m;
- int tr[me];
- int num[me];
- inline bool rulex(box a, box b)
- {
- if(a.x != b.x) return a.x < b.x;
- if(a.y != b.y) return a.y < b.y;
- return a.z < b.z;
- }
- inline bool rules(int a, int b)
- {
- if(s[a].z != s[b].z) return s[a].z < s[b].z;
- if(s[a].x != s[b].x) return s[a].x < s[b].x;
- return s[a].y < s[b].y;
- }
- inline bool ruley(box a, box b)
- {
- if(a.y != b.y) return a.y < b.y;
- return a.z < b.z;
- }
- inline int Max(int x)
- {
- int maxx = ;
- while(x > )
- {
- maxx = max(tr[x], maxx);
- x -= x & (-x);
- }
- return maxx;
- }
- inline void Ins(int x, int y)
- {
- while(x <= m)
- {
- tr[x] = max(tr[x], y);
- x += x & (-x);
- }
- }
- inline void Del(int x)
- {
- while(x <= m)
- {
- tr[x] = ;
- x += x & (-x);
- }
- }
- inline int Maxx(int x, int y)
- {
- return (x > y) ? x : y;
- }
- void Work(int l, int r)
- {
- if(l == r) return;
- int mi = l + r >> ;
- while(s[mi].x == s[mi - ].x) --mi;
- if(mi < l) return;
- Work(l, mi);
- sort(s + l, s + mi + , ruley);
- sort(s + mi + , s + r + , ruley);
- int u = l, v = mi + ;
- while(u <= mi && v <= r)
- {
- if(s[u].y < s[v].y)
- {
- Ins(s[u].z, s[u].ans);
- ++u;
- }
- else
- {
- s[v].ans = Maxx(s[v].ans, Max(s[v].z - ) + );
- ++v;
- }
- }
- for(int i = v; i <= r; ++i)
- s[i].ans = Maxx(s[i].ans, Max(s[i].z - ) + );
- for(int i = l; i <= mi; ++i) Del(s[i].z);
- sort(s + mi + , s + r + , rulex);
- Work(mi + , r);
- }
- int cc[];
- int main()
- {
- a = Get(), p = Get(), n = Get();
- cc[] = ;
- for(int i = ; i <= n; ++i)
- {
- cc[] = cc[] * a % p;
- cc[] = cc[] * a % p;
- cc[] = cc[] * a % p;
- cc[] = cc[];
- sort(cc + , cc + );
- c[i].x = cc[], c[i].y = cc[], c[i].z = cc[];
- c[i].ans = ;
- }
- sort(c + , c + + n, rulex);
- for(int i = ; i <= n; ++i)
- {
- if(c[i].x != c[i - ].x || c[i].y != c[i - ].y || c[i].z != c[i - ].z)
- {
- s[++m] = c[i];
- num[m] = m;
- }
- }
- sort(num + , num + + m, rules);
- int k = ;
- for(int i = ; i <= m; ++i)
- {
- k = i;
- while(s[num[i]].z == s[num[i + ]].z)
- {
- s[num[i]].z = k;
- ++i;
- }
- s[num[i]].z = k;
- }
- Work(, m);
- int ans = ;
- for(int i = ; i <= m; ++i)
- if(s[i].ans > ans)
- ans = s[i].ans;
- printf("%d", ans);
- }
纸箱堆叠 bzoj 2253的更多相关文章
- BZOJ 2253: [2010 Beijing wc]纸箱堆叠
题目 2253: [2010 Beijing wc]纸箱堆叠 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 239 Solved: 94 Descr ...
- 【BZOJ】【2253】【WC 2010 BeijingWC】纸箱堆叠
树套树 Orz zyf 我的树套树不知道为啥一直WA……只好copy了zyf的写法TAT 这题还可以用CDQ分治来做……但是蒟蒻不会…… //y坐标的树状数组是按权值建的……所以需要离散化…… /** ...
- BZOJ2253: [2010 Beijing wc]纸箱堆叠
题解: 其实就是求三维偏序最长链.类似于三维逆序对,我们可以用树状数组套平衡树来实现. DP方程 :f[i]=max(f[j]+1) a[j]<a[i] 我们按一维排序,另一位建立树状数组,把第 ...
- 【BZOJ2253】[2010 Beijing wc]纸箱堆叠 cdq分治
[BZOJ2253][2010 Beijing wc]纸箱堆叠 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后,即可自动化生产三边边长为 ...
- 【BZOJ2253】纸箱堆叠 [CDQ分治]
纸箱堆叠 Time Limit: 30 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description P 工厂是一个生产纸箱的工厂. 纸 ...
- BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组
BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后, ...
- 【BZOJ】2253: [2010 Beijing wc]纸箱堆叠
题意 三维严格偏序最长链.(\(n \le 50000\)) 分析 按第一维排序然后以第二和第三维作为关键字依次加入一个二维平面,维护前缀矩形最大值. 题解 当然可以树套树....可是似乎没有随机化算 ...
- bzoj2253纸箱堆叠(动态规划+cdq分治套树状数组)
Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , 之后,即可自动化生产三边边长为 (a mod P,a^2 mod p,a^3 mod P) (a^4 ...
- BZOJ2253 2010 Beijing wc 纸箱堆叠 CDQ分治
这题之前度娘上没有CDQ分治做法,gerwYY出来以后写了一个.不过要sort3遍,常数很大. gerw说可以类似划分树的思想优化复杂度,但是蒟蒻目前不会划分树(会了主席树就懒得去弄了). 嗯 将me ...
随机推荐
- 【CSS进阶】伪元素的妙用--单标签之美
最近在研读 <CSS SECRET>(CSS揭秘)这本大作,对 CSS 有了更深层次的理解,折腾了下面这个项目: CSS3奇思妙想 -- Demo (请用 Chrome 浏览器打开,非常值 ...
- iOS热更新-8种实现方式
一.JSPatch 热更新时,从服务器拉去js脚本.理论上可以修改和新建所有的模块,但是不建议这样做. 建议 用来做紧急的小需求和 修复严重的线上bug. 二.lua脚本 比如: wax.热更新时,从 ...
- [原创]mybatis中整合ehcache缓存框架的使用
mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...
- 我为Net狂 ~ 社交平台系列小集合!
微信平台: 我为Net狂(dotNetCrazy) 资源贴吧: http://tieba.baidu.com/f?kw=毒逆天 个人博客: http://dunitian.cnblogs.com/ h ...
- 我为NET狂官方面试题-数据库篇
求结果:select "1"? 查找包含"objs"的表?查找包含"o"的数据库? 求今天距离2002年有多少年,多少天? 请用一句SQL获 ...
- 立即执行函数表达式(IIFE)
原文地址:benalman.com/news/2010/11/immediately-invoked-function-expression/ 译者:nzbin 也许你还没有注意到,我是一个对术语比较 ...
- 如何在网页中提取Email地址
开博好久了,今天第一次发表技术文档,之前总是将一些好的事例保存在电脑,时间久了找起来也很麻烦,所以还是放在博客里进行归类比较方便,这样也能将自己在学习过程中的一些心得体会分享给大家,也能给需要的人一点 ...
- npm 使用小结
本文内容基于 npm 4.0.5 概述 npm (node package manager),即 node 包管理器.这里的 node 包就是指各种 javascript 库. npm 是随同 Nod ...
- c# 基础 object ,new操作符,类型转换
参考页面: http://www.yuanjiaocheng.net/webapi/config-webapi.html http://www.yuanjiaocheng.net/webapi/web ...
- [原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率
使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement 有两个方法特别值得注意:通过使用addBatch( ...