1. 程式人生 > >洛谷P4303 [AHOI2006]基因匹配(樹狀陣列)

洛谷P4303 [AHOI2006]基因匹配(樹狀陣列)

傳送門

 

我已經連這種傻逼題都不會了orz

正常的dp是$O(n^2)$的,列舉第一個陣列的$j$,然後第二個陣列的$k$,如果相等,則$dp[i]=dp[j]+1$,否則$dp[i]=dp[j]$

然後發現可以用樹狀陣列優化這個過程……

不知道講清楚沒有因為我自己都還有點懵

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 using namespace std;
 5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 6
char buf[1<<21],*p1=buf,*p2=buf; 7 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} 8 int read(){ 9 #define num ch-'0' 10 char ch;bool flag=0;int res; 11 while(!isdigit(ch=getc())) 12 (ch=='-')&&(flag=true); 13 for(res=num;isdigit(ch=getc());res=res*10
+num); 14 (flag)&&(res=-res); 15 #undef num 16 return res; 17 } 18 const int N=1e5+5; 19 int c[N],f[N][5],cnt[N],n; 20 inline void add(int x,int y){ 21 for(;x<=n;x+=x&-x) cmax(c[x],y); 22 } 23 int query(int x){ 24 int res=0;for(;x;x-=x&-x) cmax(res,c[x]);return
res; 25 } 26 int main(){ 27 // freopen("testdata.in","r",stdin); 28 n=read()*5; 29 for(int i=1,x;i<=n;++i) 30 x=read(),f[x][cnt[x]++]=i; 31 for(int i=1;i<=n;++i){ 32 int x=read(); 33 for(int j=4;j>=0;--j){ 34 int at=f[x][j]; 35 add(at,query(at-1)+1); 36 } 37 } 38 printf("%d\n",query(n)); 39 return 0; 40 }