BZOJ2253: [2010 Beijing wc]纸箱堆叠
题解:
其实就是求三维偏序最长链。类似于三维逆序对,我们可以用树状数组套平衡树来实现。
DP方程 :f[i]=max(f[j]+1) a[j]<a[i]
我们按一维排序,另一位建立树状数组,把第三维插入到每个树状数组的节点里。
除了权值之外每个节点还要保持一个mx,表示该子树内最大的f[i]。
这样就可以nlg^n了
UPD:试了下不带旋转的treap果然会被卡 orz
代码:
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 150000+5
#define maxm 4000000+5
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
#define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
#define mod 1000000007
using namespace std;
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
int n,tot,cnt,b[maxn],f[maxn],rt[maxn],c[maxn],d[maxn];
int h[maxm],mx[maxm],l[maxm],r[maxm],v[maxm],vv[maxm];
struct rec{int x,y,z;}a[maxn];
bool operator <(rec a,rec b){return a.x<b.x;}
inline void pushup(int k)
{
mx[k]=max(vv[k],max(mx[l[k]],mx[r[k]]));
}
inline void lturn(int &k)
{
int t=r[k];r[k]=l[t];l[t]=k;pushup(k);pushup(t);k=t;
}
inline void rturn(int &k)
{
int t=l[k];l[k]=r[t];r[t]=k;pushup(k);pushup(t);k=t;
}
inline void insert(int &k,int x,int y)
{
if(!k)
{
k=++tot;v[k]=x;h[k]=rand();vv[k]=mx[k]=y;
return;
}
if(x==v[k])vv[k]=max(vv[k],y);
else if(x<v[k]){insert(l[k],x,y);if(h[k]<h[l[k]])rturn(k);}
else {insert(r[k],x,y);if(h[k]<h[r[k]])lturn(k);}
pushup(k);
}
inline int getmx(int k,int x)
{
if(!k)return ;
if(v[k]==x)return max(mx[l[k]],vv[k]);
else if(x<v[k])return getmx(l[k],x);
else return max(max(mx[l[k]],vv[k]),getmx(r[k],x));
}
inline int query(int x,int y)
{
int ret=;
for(;x;x-=x&(-x)){ret=max(ret,getmx(rt[x],y));}
return ret;
}
inline void add(int x,int y,int z)
{
for(;x<=cnt;x+=x&(-x))insert(rt[x],y,z);
}
inline bool cmp(int x,int y){return b[x]<b[y];}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
ll t=read(),p=read();n=read();b[]=;
for1(i,*n)b[i]=(ll)b[i-]*t%p,c[i]=i;
sort(c+,c+*n+,cmp);
cnt=;
for1(i,*n)
{
if(i==||b[c[i]]!=b[c[i-]])cnt++;
d[c[i]]=cnt;
}
for1(i,n)a[i].x=d[*i-],a[i].y=d[*i-],a[i].z=d[*i];
for1(i,n)
{
if(a[i].y>a[i].x)swap(a[i].x,a[i].y);
if(a[i].z>a[i].x)swap(a[i].x,a[i].z);
if(a[i].z>a[i].y)swap(a[i].z,a[i].y);
}
sort(a+,a+n+);
for(int l=,r=;l<=n;r++,l=r)
{
while(a[r+].x==a[l].x)r++;
for2(i,l,r)f[i]=query(a[i].y-,a[i].z-)+;//cout<<i<<' '<<f[i]<<endl;
for2(i,l,r)add(a[i].y,a[i].z,f[i]);
}
int ans=;
for1(i,n)ans=max(ans,f[i]);
cout<<ans<<endl;
return ;
}
2253: [2010 Beijing wc]纸箱堆叠
Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 246 Solved: 96
[Submit][Status]
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)。其中只有
(4, 6, 9)可堆叠进(5, 16, 7),故答案为 2。
2<=P<=2000000000,1<=a<=p-1,a^k mod p<>0,ap<=2000000000,1<=N<=50000
BZOJ2253: [2010 Beijing wc]纸箱堆叠的更多相关文章
- BZOJ2253 2010 Beijing wc 纸箱堆叠 CDQ分治
这题之前度娘上没有CDQ分治做法,gerwYY出来以后写了一个.不过要sort3遍,常数很大. gerw说可以类似划分树的思想优化复杂度,但是蒟蒻目前不会划分树(会了主席树就懒得去弄了). 嗯 将me ...
- 【BZOJ2253】[2010 Beijing wc]纸箱堆叠 cdq分治
[BZOJ2253][2010 Beijing wc]纸箱堆叠 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后,即可自动化生产三边边长为 ...
- BZOJ 2253: [2010 Beijing wc]纸箱堆叠
题目 2253: [2010 Beijing wc]纸箱堆叠 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 239 Solved: 94 Descr ...
- 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\)) 分析 按第一维排序然后以第二和第三维作为关键字依次加入一个二维平面,维护前缀矩形最大值. 题解 当然可以树套树....可是似乎没有随机化算 ...
- 【BZOJ】【2253】【WC 2010 BeijingWC】纸箱堆叠
树套树 Orz zyf 我的树套树不知道为啥一直WA……只好copy了zyf的写法TAT 这题还可以用CDQ分治来做……但是蒟蒻不会…… //y坐标的树状数组是按权值建的……所以需要离散化…… /** ...
- bzoj 2252 [ 2010 Beijing wc ] 矩阵距离 —— 多源bfs
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2252 又没能自己想出来... 一直在想如何从每个1开始广搜更新答案,再剪剪枝,什么遇到1就不 ...
- 【BZOJ2253】纸箱堆叠 [CDQ分治]
纸箱堆叠 Time Limit: 30 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description P 工厂是一个生产纸箱的工厂. 纸 ...
- 纸箱堆叠 bzoj 2253
纸箱堆叠 (1s 128MB) box [问题描述] P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n, p, a 之后,即可自动化生产三边边长为 (a mod P, a^2 mod p ...
随机推荐
- IOS7 适配时导航栏变黑
当适配IOS的布局时遇到问题:导航栏和菜单栏后台会变黑色. self.edgesForExtendedLayout = UIRectEdgeNone; 原因是系统默认这两个控件是半通明的. 解决方案: ...
- java代码判断图片文件格式, 不是根据文件后缀来判断。
public static final String TYPE_JPG = "jpg"; public static final String TYPE_GIF = "g ...
- hdu 1517 A Multiplication Game 博弈论
思路:求必胜区间和必败区间! 1-9 先手胜 10-2*9后手胜 19-2*9*9先手胜 163-2*2*9*9后手胜 …… 易知右区间按9,2交替出现的,所以每次除以18,直到小于18时就可以直接判 ...
- linux入门教程(六) Linux文件与目录管理
在linux中什么是一个文件的路径呢,说白了就是这个文件存在的地方,例如在上一章提到的/root/.ssh/authorized_keys 这就是一个文件的路径.如果你告诉系统这个文件的路径,那么系统 ...
- C++客户端程序(socket)
// MyClient.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h"#include "stdio.h"#include ...
- ASP.NET中App_Code,App_Data等文件夹的作用
http://www.cnblogs.com/shiyu007/archive/2007/12/04/982264.html 1. Bin文件夹 Bin文件夹包含应用程序所需的,用于控件.组件或者需 ...
- iOS开发--即时通讯
什么是环信? 1.环信是一个第三平台,提供即时通信(IM–Instant Messaging )的服务 2.环信是在XMPP的基础上进行二次开发 3.环信在网络上传输的数据也是XML 4.使用环信,不 ...
- React测试Mixin
1.test.jsx var randomNumberMixin = require("./randomNumberMixin.jsx"); describe("test ...
- Android系统
系统内核 Android 是运行于Linux kernel之上,但并不是GNU/Linux. 因为在一般GNU/Linux 里支持的功能,Android 大都没有支持,包括Cairo.X11.Al ...
- 修改Eclipse字体
选择菜单:Windows->Preferences->Genneral->Appearance->Colors and Font