• bjoi 2010 纸箱堆叠 二维树状数组


    题意: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个纸箱中数量最多的一个子集,使得它们两两之间都可
    嵌套堆叠起来。

    2<=P<=2000000000,1<=a<=p-1,a^k mod p<>0,ap<=2000000000,1<=N<=50000

    思路:先把n个纸箱求出来

    按一维排序 另两维用二维树状数组

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<map>
      5 #include<cmath>
      6 #include<algorithm>
      7 using namespace std;
      8 #define MAXN 50000+100
      9 struct number
     10 {
     11     long long x,y,z;
     12 };
     13 int n,ans=0;
     14 long long t,p;
     15 long long b[MAXN];
     16 number a[MAXN];
     17 map<pair<int,int>,int> tree;
     18 map<long long,int> home;
     19 void my_sort(int i)
     20 {
     21     if(a[i].x>a[i].y) swap(a[i].x,a[i].y);
     22     if(a[i].y>a[i].z) swap(a[i].z,a[i].y);
     23     if(a[i].x>a[i].y) swap(a[i].x,a[i].y);
     24 }
     25 bool cmp(const number &A,const number &B)
     26 {
     27     if(A.x<B.x) return 1;
     28     if(A.x>B.x) return 0;
     29     if(A.y>B.y) return 1;
     30     return 0;
     31 }
     32 
     33 void make_a()
     34 {
     35     int i;
     36     long long temp=1;
     37     for(i=1;i<=3*n;i++)
     38     {
     39         temp=temp*t%p;
     40         if(i%3==1) a[i/3+1].x=temp;
     41         else if(i%3==2) a[i/3+1].y=temp;
     42         else
     43         {
     44             a[i/3].z=temp;
     45             my_sort(i/3);
     46         }
     47     }
     48     sort(a+1,a+n+1,cmp);
     49 }
     50 void discretization()
     51 {
     52     b[0]=-1;
     53     int i,j=0;
     54     for(i=1;i<=n;i++)
     55         b[i]=a[i].y;
     56     sort(b,b+n+1);
     57     for(i=1;i<=n;i++)
     58     {
     59         if(b[i]!=b[i-1])
     60             home[b[i]]=++j;
     61         else
     62             home[b[i]]=j;
     63     }
     64     for(i=1;i<=n;i++) a[i].y=home[a[i].y];
     65 
     66     for(i=1;i<=n;i++)
     67         b[i]=a[i].z;
     68     sort(b,b+n+1);
     69     j=0;
     70     for(i=1;i<=n;i++)
     71     {
     72         if(b[i]!=b[i-1])
     73             home[b[i]]=++j;
     74         else
     75             home[b[i]]=j;
     76     }
     77     for(i=1;i<=n;i++)
     78         a[i].z=home[a[i].z];
     79 }
     80 int lowbit(int x)
     81 {
     82     return x&(x^(x-1));
     83 }
     84 void update(int x,int y,int add)
     85 {
     86     for(int i=x;i<=n;i+=lowbit(i))
     87         for(int j=y;j<=n;j+=lowbit(j))
     88             tree[make_pair(i,j)]=max(tree[make_pair(i,j)],add);
     89 }
     90 int find(int x,int y)
     91 {
     92     int ans=0;
     93     for(int i=x;i>0;i-=lowbit(i))
     94         for(int j=y;j>0;j-=lowbit(j))
     95             ans=max(ans,tree[make_pair(i,j)]);
     96     return ans;
     97 }
     98 
     99 int main()
    100 {
    101     int temp;
    102     scanf("%lld%lld%d",&t,&p,&n);
    103     make_a();
    104     discretization();
    105     for(int i=1;i<=n;i++)
    106     {
    107         temp=find(a[i].y-1,a[i].z-1);
    108         update(a[i].y,a[i].z,temp+1);
    109         if(temp+1>ans) ans=temp+1;
    110     }
    111     printf("%d\n",ans);
    112     return 0;
    113 }
  • 相关阅读:
    框架——缓存框架——redis——功能——脚本
    框架——日志框架——logback——核心流程
    框架——缓存框架——redis——功能——安全(security)
    框架——日志框架——logback——配置文件
    框架——日志框架——logback——初篇
    博客导航
    框架——日志框架——logback——搭建环境
    卡掉线段树
    51nod 模拟4
    51nod 模拟2
  • 原文地址:https://www.cnblogs.com/myoi/p/2441188.html
Copyright © 2020-2023  润新知