网站vr视角怎么做,网站建设及相关流程图,一级a做爰片2202网站,北京建设网站哪里好正题
题目链接:https://www.luogu.com.cn/problem/P3971 题目大意
一个1∼n1\sim n1∼n的一个排列#xff0c;设aia_iai表示以iii结尾的最长上升子序列长度#xff0c;bib_ibi表示以iii开头的最长下降子序列长度。
给出序列aaa求序列bbb的最大和。 1≤n≤1051\leq n\l…正题
题目链接:https://www.luogu.com.cn/problem/P3971 题目大意
一个1∼n1\sim n1∼n的一个排列设aia_iai表示以iii结尾的最长上升子序列长度bib_ibi表示以iii开头的最长下降子序列长度。
给出序列aaa求序列bbb的最大和。
1≤n≤1051\leq n\leq 10^51≤n≤105 解题思路
考虑数组aaa带来的限制
对于一个aiajw(ij)a_ia_jw(ij)aiajw(ij)那么有xixjx_ix_jxixj对于一个ajw1a_jw1ajw1前一个最近的aiwa_iwaiw那么有xixjx_ix_jxixj
第一个限制其实不用管因为如果我们要最优一定会满足那个限制。
考虑第二个限制我们将iii向jjj连一条边这样我们就可以得到一棵树把000视为虚根的话。
那么我们子节点的权值一定要比父节点的大然后在满足这个的前提下我们优先扩展编号大的节点就好了。
也就是从大到小跑一遍dfsdfsdfs序就可以得到xxx数组。
然后用树状数组统计一下答案。
时间复杂度O(nlogn)O(n\log n)O(nlogn) code
#includecstdio
#includecstring
#includealgorithm
#define lowbit(x) (x-x)
using namespace std;
const int N1e510;
struct node{int to,next;
}a[N];
int n,tot,cnt,dfn[N],ls[N],t[N],las[N];
long long ans;
void addl(int x,int y){a[tot].toy;a[tot].nextls[x];ls[x]tot;return;
}
void dfs(int x){dfn[x]cnt;for(int ils[x];i;ia[i].next)dfs(a[i].to);return;
}
void Change(int x,int val){while(xn){t[x]max(t[x],val);xlowbit(x);}return;
}
int Ask(int x){int ans0;while(x){ansmax(ans,t[x]);x-lowbit(x);}return ans;
}
int main()
{scanf(%d,n);for(int i1;in;i){int x;scanf(%d,x);addl(las[x-1],i);las[x]i; }cnt-1;dfs(0);for(int in;i1;i--){int tAsk(dfn[i])1;anst;Change(dfn[i],t);}printf(%lld\n,ans);return 0;
}