BZOJ 2253: [2010 Beijing wc]纸箱堆叠
题目
2253: [2010 Beijing wc]纸箱堆叠
Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 239 Solved: 94
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。
2<=P<=2000000000,1<=a<=p-1,a^k mod p<>0,ap<=2000000000,1<=N<=50000
HINT
Source
题解
开始开坑刷WC的题,这一道题主体思路反正就是统计x,y,z都小于自己的有多少个。第一维用排序,剩下两维用二维树状数组。统计最大值就可以了,话说我也一下子Get到了树状数组最大值Orz= =,然后其中需要暴力离散化一下,p太大了。
代码
1 /*Author:WNJXYK*/ 2 #include<cstdio> 3 #include<algorithm> 4 #include<map> 5 using namespace std; 6 7 const int Maxn=50010; 8 map<pair<int,int>,int> tree; 9 10 struct Box{ 11 long long x,y,z; 12 Box(){} 13 inline void swap(long long &x,long long &y){ 14 long long tmp=x; 15 x=y; 16 y=tmp; 17 } 18 Box(long long a,long long b,long long c){ 19 if (a>b) swap(a,b); 20 if (b>c) swap(b,c); 21 if (a>b) swap(a,b); 22 x=a;y=b;z=c; 23 } 24 }; 25 Box b[50010]; 26 bool cmp(Box a,Box b){ 27 if (a.x<b.x) return true; 28 if (a.x==b.x && a.y<b.y) return true; 29 if (a.x==b.x && a.y==b.y && a.z<b.z) return true; 30 return false; 31 } 32 33 inline int lowbit(int x){ 34 return x&-x; 35 } 36 37 inline int remax(int a,int b){ 38 if (a<b) return b; 39 return a; 40 } 41 42 inline void update(int x,int y,int val){ 43 for (int i=x;i<=Maxn;i+=lowbit(i)){ 44 for (int j=y;j<=Maxn;j+=lowbit(j)){ 45 tree[make_pair(i,j)]=remax(tree[make_pair(i,j)],val); 46 } 47 } 48 } 49 50 inline int getAns(int x,int y){ 51 int res=0; 52 for (int i=x;i;i-=lowbit(i)){ 53 for (int j=y;j;j-=lowbit(j)){ 54 res=remax(res,tree[make_pair(i,j)]); 55 } 56 } 57 return res; 58 } 59 60 long long a,n,p; 61 62 int index; 63 int hash[50010]; 64 map<long long,int> delta; 65 66 int main(){ 67 scanf("%lld%lld%lld",&a,&p,&n); 68 int x,y,z; 69 long long tmp=1; 70 for (int i=1;i<=n;i++){ 71 tmp=((long long)tmp*(long long)a)%(long long)p; 72 x=tmp; 73 tmp=((long long)tmp*(long long)a)%(long long)p; 74 y=tmp; 75 tmp=((long long)tmp*(long long)a)%(long long)p; 76 z=tmp; 77 b[i]=Box(x,y,z); 78 } 79 sort(b+1,b+n+1,cmp); 80 81 hash[0]=-1; 82 index=0; 83 for (int i=1;i<=n;i++)hash[i]=b[i].y; 84 sort(hash+1,hash+n+1); 85 for (int i=1;i<=n;i++)if (hash[i]>hash[i-1]) delta[hash[i]]=++index; else delta[hash[i]]=index; 86 for (int i=1;i<=n;i++) b[i].y=delta[b[i].y]; 87 hash[0]=-1; 88 index=0; 89 for (int i=1;i<=n;i++)hash[i]=b[i].z; 90 sort(hash+1,hash+n+1); 91 for (int i=1;i<=n;i++)if (hash[i]>hash[i-1]) delta[hash[i]]=++index; else delta[hash[i]]=index; 92 for (int i=1;i<=n;i++) b[i].z=delta[b[i].z]; 93 94 int Ans=0; 95 for (int i=1;i<=n;i++){ 96 tmp=getAns(b[i].y-1,b[i].z-1); 97 update(b[i].y,b[i].z,tmp+1); 98 Ans=remax(tmp+1,Ans); 99 } 100 101 printf("%d\n",Ans); 102 103 return 0; 104 }