【bzoj1264】[AHOI2006]基因匹配Match 树状数组
题解:
一道比较简单的题目
容易发现状态数只有5*n个
而转移需要满足i1<i2;j1<j2
那么很明显是二维平面数点
暴力一点就是二维树状数组+map
5nlog^3 比较卡常
但是注意到我们的dp是保证了i1<i2的
所以本质是扫描线+树状数组
5nlogn
由于代码非常简单编译调试一遍过
代码:
#include <bits/stdc++.h> using namespace std; #define IL inline #define rint register int #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) #define mid ((h+t)/2) #define me(x) memset(x,0,sizeof(x)) #define lowbit(x) (x&(-x)) const int N=2e5; int n,a[N],b[N],f[N][6],cnt[N]; char ss[1<<24],*A=ss,*B=ss; IL char gc() { return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; } template<class T>IL void read(T &x) { rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48); while (c=gc(),47<c&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; } IL void maxx(int &x,int y) { if (x<y) x=y; } struct sgt{ int data[N]; int query(int x) { int ans=0; while (x) { maxx(ans,data[x]); x-=lowbit(x); } return(ans); } void insert(int x,int y) { while (x<=n) { maxx(data[x],y); x+=lowbit(x); } } }S; int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); read(n); n*=5; rep(i,1,n) read(a[i]); rep(i,1,n) read(b[i]); rep(i,1,n) f[b[i]][++cnt[b[i]]]=i; int ans=0; rep(i,1,n) dep(j,5,1) { int kk=S.query(f[a[i]][j]-1)+1; S.insert(f[a[i]][j],kk); maxx(ans,kk); } cout<<ans<<endl; return 0; }