【BZOJ】【2253】【WC 2010 BeijingWC】纸箱堆叠
树套树
Orz zyf
我的树套树不知道为啥一直WA……只好copy了zyf的写法TAT
这题还可以用CDQ分治来做……但是蒟蒻不会……
//y坐标的树状数组是按权值建的……所以需要离散化……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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\n",ans); 111 return 0; 112 } 113 //y坐标的树状数组是按权值建的……所以需要离散化……