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

时间:2021-12-24 05:32:47

树套树


  Orz zyf

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

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

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

 /**************************************************************
Problem: 2253
User: Tunix
Language: C++
Result: Accepted
Time:2808 ms
Memory:76280 kb
****************************************************************/ //BZOJ 2253
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
#define CC(a,b) memset(a,b,sizeof(a))
using namespace std;
int getint(){
int v=,sign=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') sign=-; ch=getchar();}
while(isdigit(ch)) {v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=,M=,INF=~0u>>;
typedef long long LL;
const double eps=1e-;
/*******************template********************/
int n,tot,l[M],r[M],s[M],rnd[M],v[M],f[N],mx[M];
#define L l[x]
#define R r[x]
inline void Push_up(int x){ mx[x]=max(max(mx[L],mx[R]),s[x]); }
inline void zig(int &x){int t=L; L=r[t]; r[t]=x; Push_up(x); Push_up(t); x=t;}
inline void zag(int &x){int t=R; R=l[t]; l[t]=x; Push_up(x); Push_up(t); x=t;}
void ins(int &x,int val,int num){
if (!x){
x=++tot; v[x]=val; s[x]=mx[x]=num; L=R=; rnd[x]=rand(); return;
}
if(v[x]==val) s[x]=max(s[x],num);
else if(val<v[x]){
ins(L,val,num); if (rnd[L]<rnd[x]) zig(x);
}else{
ins(R,val,num); if (rnd[R]<rnd[x]) zag(x);
}
Push_up(x);
}
int rank(int x,int val){
if (!x) return ;
if (v[x]==val) return max(mx[L],s[x]);
else if (val<v[x]) return rank(L,val);
else return max(max(s[x],mx[L]),rank(R,val));
}
#undef L
#undef R
/********************Treap**********************/
int rt[N],_num,b[N],c[N],d[N];
void update(int x,int val,int num){
for(int i=x;i<=_num;i+=i&-i) ins(rt[i],val,num);
}
int query(int x,int val){
int ans=;
for(int i=x;i;i-=i&-i) ans=max(ans,rank(rt[i],val));
return ans;
}
/*******************Fenwick*********************/
struct data{
int x,y,z;
}a[N];
bool cmp(data a,data b){
return a.x<b.x;
}
bool cmp2(int x,int y){return b[x]>b[y];}
void init(){
LL A=getint(),P=getint();
n=getint();
b[]=;
F(i,,n*) b[i]=(LL)b[i-]*A%P,c[i]=i;
sort(c+,c+*n+,cmp2);
_num=;
F(i,,*n){
if (i== || b[c[i]]!=b[c[i-]]) _num++;
d[c[i]]=_num;
}
F(i,,n) a[i].x=d[*i-],a[i].y=d[*i-],a[i].z=d[*i];
F(i,,n){
if (a[i].y>a[i].x) swap(a[i].x,a[i].y);
if (a[i].z>a[i].x) swap(a[i].x,a[i].z);
if (a[i].z>a[i].y) swap(a[i].y,a[i].z);
}
sort(a+,a+n+,cmp);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
init();
int ans=;
for(int l=,r=;l<=n;r++,l=r){
while(a[r+].x==a[l].x) r++;
F(i,l,r) f[i]=query(a[i].y-,a[i].z-)+;
F(i,l,r) update(a[i].y,a[i].z,f[i]);
}
F(i,,n) ans=max(f[i],ans);
printf("%d\n",ans);
return ;
}
//y坐标的树状数组是按权值建的……所以需要离散化……