P3402 最长公共子序列
经典问题
LCS-->LIS
没有重复的值才可以这么做
把第一数列转化成1~n,然后将第二个数列映射成1~n中的一些数,然后求第二个数列的LIS即可,然后用Bit求LIS,O(nlogN)
//数据太大,考虑map
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<map> #include<cstring> #define inf 2147483647 #define For(i,a,b) for(register int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() //by war //2017.10.17 using namespace std; int n,m; int t[300010]; int ans; int f[300010]; int a[300010]; int b[300010]; int x; map<int,int>c; void in(int &x) { int y=1; char c=g();x=0; while(c<'0'||c>'9') { if(c=='-') y=-1; c=g(); } while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); x*=y; } void o(int x) { if(x<0) { p('-'); x=-x; } if(x>9)o(x/10); p(x%10+'0'); } int getmax(int k) { int Max=0; for(;k>0;k-=(-k)&k) Max=max(Max,t[k]); return Max; } void modify(int k,int Max) { for(;k<=n;k+=(-k)&k) t[k]=max(t[k],Max); } int main() { in(n),in(m); For(i,1,n) in(b[i]),c[b[i]]=i; For(i,1,m) in(a[i]); For(i,1,m) a[i]=c[a[i]]; For(i,1,m) { f[i]=getmax(a[i])+1; ans=max(ans,f[i]); if(a[i]>0) modify(a[i],f[i]); } o(ans); return 0; }
我今天才算搞懂最长公共子序列的nlogn的做法,下面的是任何情况都适用的
5 4 1 1 2
1 2 4,3 4,3 5
1 1 4
4 3 4 3 5
在4 3 4 3 5里面求严格递增的LIS就是二者的LCS
#include <bits/stdc++.h> #define inf 2147483647 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<=b;++i) //by war //2020.4.24 using namespace std; long long n,m,cnt; long long t[N],a[N],b[N],temp[N]; long long ans0,ans1; long long x; map<long long,long long>c,d; vector<long long>v[N],u; stack<int>st; void in(long long &x){ long long y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(long long x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } long long getmax(long long k){ long long Max=0; for(;k>0;k-=(-k)&k) Max=max(Max,t[k]); return Max; } void modify(long long k,long long Max){ for(;k<=cnt;k+=(-k)&k) t[k]=max(t[k],Max); } signed main(){ in(n);in(m); For(i,1,n){ in(b[i]); if(c[b[i]]==0){ c[b[i]]=i; v[i].push_back(i); } else v[c[b[i]]].push_back(i); temp[i]=b[i]; } sort(temp+1,temp+n+1); For(i,1,n) d[temp[i]]=i; For(i,1,n) b[i]=d[b[i]],u.push_back(b[i]); cnt=u.size(); for(auto i:u){ long long cc=getmax(i-1)+1; ans0=max(ans0,cc); modify(i,cc); } u.clear(); For(i,1,m) in(a[i]); For(i,1,m){ if(c[a[i]]!=0){ for(auto j:v[c[a[i]]]) st.push(j); while(!st.empty()) u.push_back(st.top()),st.pop(); } } memset(t,0,sizeof(t)); for(auto i:u){ long long cc=getmax(i-1)+1; ans1=max(ans1,cc); modify(i,cc); } o(ans0);p(' ');o(ans1); return 0; }