【BZOJ】【2253】【WC 2010 BeijingWC】纸箱堆叠

树套树


  Orz zyf

  我的树套树不知道为啥一直WA……只好copy了zyf的写法TAT

  这题还可以用CDQ分治来做……但是蒟蒻不会……

//y坐标的树状数组是按权值建的……所以需要离散化……

  1 /**************************************************************
  2     Problem: 2253
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:2808 ms
  7     Memory:76280 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 2253
 11 #include<cmath>
 12 #include<vector>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<cstdlib>
 16 #include<iostream>
 17 #include<algorithm>
 18 #define rep(i,n) for(int i=0;i<n;++i)
 19 #define F(i,j,n) for(int i=j;i<=n;++i)
 20 #define D(i,j,n) for(int i=j;i>=n;--i)
 21 #define pb push_back
 22 #define CC(a,b) memset(a,b,sizeof(a))
 23 using namespace std;
 24 int getint(){
 25     int v=0,sign=1; char ch=getchar();
 26     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
 27     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
 28     return v*sign;
 29 }
 30 const int N=150010,M=3000000,INF=~0u>>2;
 31 typedef long long LL;
 32 const double eps=1e-8;
 33 /*******************template********************/
 34 int n,tot,l[M],r[M],s[M],rnd[M],v[M],f[N],mx[M];
 35 #define L l[x]
 36 #define R r[x]
 37 inline void Push_up(int x){ mx[x]=max(max(mx[L],mx[R]),s[x]); }
 38 inline void zig(int &x){int t=L; L=r[t]; r[t]=x; Push_up(x); Push_up(t); x=t;}
 39 inline void zag(int &x){int t=R; R=l[t]; l[t]=x; Push_up(x); Push_up(t); x=t;}
 40 void ins(int &x,int val,int num){
 41     if (!x){
 42         x=++tot; v[x]=val; s[x]=mx[x]=num; L=R=0; rnd[x]=rand(); return;
 43     }
 44     if(v[x]==val) s[x]=max(s[x],num);
 45     else if(val<v[x]){
 46         ins(L,val,num); if (rnd[L]<rnd[x]) zig(x);
 47     }else{
 48         ins(R,val,num); if (rnd[R]<rnd[x]) zag(x);
 49     }
 50     Push_up(x);
 51 }
 52 int rank(int x,int val){
 53     if (!x) return 0;
 54     if (v[x]==val) return max(mx[L],s[x]);
 55     else if (val<v[x]) return rank(L,val);
 56     else return max(max(s[x],mx[L]),rank(R,val));
 57 }
 58 #undef L
 59 #undef R
 60 /********************Treap**********************/
 61 int rt[N],_num,b[N],c[N],d[N];
 62 void update(int x,int val,int num){
 63     for(int i=x;i<=_num;i+=i&-i) ins(rt[i],val,num);
 64 }
 65 int query(int x,int val){
 66     int ans=0;
 67     for(int i=x;i;i-=i&-i) ans=max(ans,rank(rt[i],val));
 68     return ans;
 69 }
 70 /*******************Fenwick*********************/
 71 struct data{
 72     int x,y,z;
 73 }a[N];
 74 bool cmp(data a,data b){
 75     return a.x<b.x;
 76 }
 77 bool cmp2(int x,int y){return b[x]>b[y];}
 78 void init(){
 79     LL A=getint(),P=getint();
 80     n=getint();
 81     b[0]=1;
 82     F(i,1,n*3) b[i]=(LL)b[i-1]*A%P,c[i]=i;
 83     sort(c+1,c+3*n+1,cmp2);
 84     _num=0;
 85     F(i,1,3*n){
 86         if (i==1 || b[c[i]]!=b[c[i-1]]) _num++;
 87         d[c[i]]=_num;
 88     }
 89     F(i,1,n) a[i].x=d[3*i-2],a[i].y=d[3*i-1],a[i].z=d[3*i];
 90     F(i,1,n){
 91         if (a[i].y>a[i].x) swap(a[i].x,a[i].y);
 92         if (a[i].z>a[i].x) swap(a[i].x,a[i].z);
 93         if (a[i].z>a[i].y) swap(a[i].y,a[i].z);
 94     }
 95     sort(a+1,a+n+1,cmp);
 96 }
 97 int main(){
 98 #ifndef ONLINE_JUDGE
 99     freopen("input.txt","r",stdin);
100 //  freopen("output.txt","w",stdout);
101 #endif
102     init();
103     int ans=0;
104     for(int l=1,r=1;l<=n;r++,l=r){
105         while(a[r+1].x==a[l].x) r++;
106         F(i,l,r) f[i]=query(a[i].y-1,a[i].z-1)+1;
107         F(i,l,r) update(a[i].y,a[i].z,f[i]);
108     }
109     F(i,1,n) ans=max(f[i],ans);
110     printf("%d
",ans);
111     return 0;
112 }
113 //y坐标的树状数组是按权值建的……所以需要离散化…… 
View Code
原文地址:https://www.cnblogs.com/Tunix/p/4343834.html