• 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
  • 相关阅读:
    MySQL的小Tips
    Linux中Eclipse下搭建Web开发环境
    SaaS的那些事儿
    典型的软件过程模型
    浅谈「敏捷」开发
    软件工程的本质
    堆和优先队列
    c 判断文件或文件夹是否存在,多种方法, 为什么从一开始就不直接来个统一的呢?
    大江河流尽
    jpg、png格式的图片转换成webp后颜色失真的问题
  • 原文地址:https://www.cnblogs.com/WNJXYK/p/4161733.html
Copyright © 2020-2023  润新知