Submission #466995

#TimeUsernameProblemLanguageResultExecution timeMemory
466995TlenekWodoruExam (eJOI20_exam)C++14
100 / 100
148 ms9236 KiB
#include <bits/stdc++.h> using namespace std; int A[100009]; int B[100009]; pair<int,int>granica[100009]; int dp[2][100009]; int DOR[100009]; map<int,int>miejsce; int Tre[1000000]; int t,t2; void Przedzial(int l, int p, int dod) { l+=t2; p+=t2; int v=1; int P=t2+1; while(true) { if(v*P+P-1<l) { v=v/2; P=P*2; if(v==0){break;} } else if(v*P==l&&v*P+P-1<=p) { Tre[v]=max(Tre[v],dod); l+=P; } else { if(l<v*P+(P/2)) { v=v*2; P=P/2; } else { v=v*2+1; P=P/2; } } } } int punkt(int v) { int maxx=0; v+=t2; while(v!=0) { maxx=max(maxx,Tre[v]); v=v/2; } return maxx; } int TworzenieDrzewa(int x) { int u=x; int coss=0; while(u>0) { coss++; u=u/2; } if(pow(2,coss-1)==x){coss--;} coss++; return coss; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n;cin>>n; for(int i=1;i<=n;i++) { cin>>A[i]; } for(int i=1;i<=n;i++) { cin>>B[i]; } map<int,int>M; M[2000000000]=0; for(int i=1;i<=n;i++) { granica[i].first=M.upper_bound(A[i])->second+1; while(M.size()>0&&M.begin()->first<=A[i]) { M.erase(M.begin()->first); } M[A[i]]=i; } M.clear(); M[2000000000]=n+1; for(int i=n;i>=1;i--) { granica[i].second=M.upper_bound(A[i])->second-1; while(M.size()>0&&M.begin()->first<=A[i]) { M.erase(M.begin()->first); } M[A[i]]=i; } M.clear(); ///-=-==-=-==-=-==-=-==-=-==-=-=-==-=--=-==-=-=- bool cv=1; for(int i=2;i<=n;i++) { if(B[i-1]!=B[i]) { cv=0; break; } } if(n<=5000) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(A[i]==B[j]&&granica[i].first<=j&&j<=granica[i].second) { dp[i%2][j]=dp[i%2][j-1]+1; } else { dp[i%2][j]=max(dp[i%2][j-1],dp[(i-1)%2][j]); } } } cout<<dp[n%2][n]<<endl; } else if(cv==1) { for(int i=1;i<=n;i++) { if(A[i]==B[1]) { DOR[granica[i].first]++; DOR[granica[i].second+1]--; } } int wynik=0; for(int i=1;i<=n;i++) { DOR[i]+=DOR[i-1]; if(DOR[i]>0) { wynik++; } } cout<<wynik<<endl; } else { for(int i=1;i<=n;i++) { miejsce[A[i]]=i; } t=TworzenieDrzewa(n); t2=pow(2,t-1)-1; for(int i=1;i<=n;i++) { int ind=miejsce[B[i]]; if(ind!=0&&granica[ind].first<=i&&i<=granica[ind].second) { int dod=punkt(ind)+1; Przedzial(ind,n,dod); } } cout<<punkt(n)<<endl; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...