这道题感觉有点意思.
由于每个B串中每个点的在A串中匹配位置只有常数个.
因此对于每个点可以枚举在A串中的匹配位置,然后此处的函数值需要更新为max(f[i],max(f[j])+1); 1<=j<i
这道题也就被转化成了动态前缀最大值问题,线段树可切,但更方便的是树状数组.
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define FILE "dealing" 5 #define up(i,j,n) for(int i=j;i<=n;i++) 6 #define db long double 7 #define pii pair<int,int> 8 #define pb push_back 9 #define mem(a,L) memset(a,0,sizeof(int)*(L+1)) 10 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;} 11 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;} 12 template<class T> inline T squ(T a){return a*a;} 13 const ll maxn=100100+10,inf=1e9+10,limit=1e7; 14 ll read(){ 15 ll x=0,f=1,ch=getchar(); 16 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 17 while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); 18 return x*f; 19 } 20 int n,m,a[maxn],b[maxn]; 21 int f[maxn]; 22 vector<int> v[maxn]; 23 int c[maxn]; 24 int lowbit(int x){return x&-x;} 25 void add(int x,int d){ 26 while(x<=m)cmax(c[x],d),x+=lowbit(x); 27 } 28 int get(int x){ 29 int ans=0; 30 while(x)cmax(ans,c[x]),x-=lowbit(x); 31 return ans; 32 } 33 int main(){ 34 freopen(FILE".in","r",stdin); 35 freopen(FILE".out","w",stdout); 36 n=read();m=5*n; 37 up(i,1,m)a[i]=read(),v[a[i]].push_back(i); 38 up(i,1,m)b[i]=read(); 39 up(i,1,m){ 40 for(int j=4;j>=0;j--){ 41 int pos=v[b[i]][j]; 42 add(pos,get(pos-1)+1); 43 } 44 } 45 int ans=0; 46 up(i,1,m)cmax(ans,c[i]); 47 printf("%d ",ans); 48 return 0; 49 }