【Luogu】P3971Alice And Bob(贪心)
容易发现值为x的点只可能从值为x-1的点转移过来,所以我们把原序列连成一棵树,dfs序就是原序列的一种形式。
就可以直接求啦
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cctype> #define maxn 200000 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } struct Edge{ int next,to; }edge[maxn]; int head[maxn],num; inline void add(int from,int to){ edge[++num]=(Edge){head[from],to}; head[from]=num; } int s[maxn]; int dfn[maxn],ID=-1; int d[maxn]; int q[maxn]; void dfs(int x){ dfn[x]=++ID; for(int i=head[x];i;i=edge[i].next){ int to=edge[i].to; dfs(to); } } int calc(int lim,int n){ int now=upper_bound(d+1,d+n+1,lim)-d; d[now]=min(d[now],lim); return now; } int main(){ memset(d,127,sizeof(d)); int n=read(); for(int i=1;i<=n;++i){ int x=read(); add(s[x-1],i); s[x]=i; } dfs(0); long long ans=0; for(int i=n;i>=1;--i) ans+=calc(dfn[i],n); printf("%lld\n",ans); return 0; }