• BZOJ 2253: [2010 Beijing wc]纸箱堆叠


    题目

    2253: [2010 Beijing wc]纸箱堆叠

    Time Limit: 30 Sec  Memory Limit: 256 MB
    Submit: 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

     
    [Submit][Status]

    题解

    开始开坑刷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
    ",Ans);
    102     
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    HDU 5583 Kingdom of Black and White 水题
    HDU 5578 Friendship of Frog 水题
    Codeforces Round #190 (Div. 2) E. Ciel the Commander 点分治
    hdu 5594 ZYB's Prime 最大流
    hdu 5593 ZYB's Tree 树形dp
    hdu 5592 ZYB's Game 树状数组
    hdu 5591 ZYB's Game 博弈论
    HDU 5590 ZYB's Biology 水题
    cdoj 1256 昊昊爱运动 预处理/前缀和
    cdoj 1255 斓少摘苹果 贪心
  • 原文地址:https://www.cnblogs.com/WNJXYK/p/4161733.html
Copyright © 2020-2023  润新知