题目大意

题目分析
有性质:$x$一定与$x$的前驱后继相邻。
因此可以模拟题目的操作,任何可以查询前驱后继的数据结构都可以使用。
所以有了很多用$set$水过的人,我选择双向链表。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std; typedef long long LL; inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj; } const int maxn=300005; int n,a[maxn],Left[maxn],Right[maxn],f[maxn],g[maxn]; LL Depth[maxn],sum=0; int main() { n=Get_Int(); for(int i=1; i<=n; i++) { a[i]=Get_Int(); Left[i]=i-1; Right[i]=i+1; } Right[n]=0; for(int i=n; i>1; i--) { f[a[i]]=Left[a[i]]; g[a[i]]=Right[a[i]]; if(Right[a[i]])Left[Right[a[i]]]=Left[a[i]]; if(Left[a[i]])Right[Left[a[i]]]=Right[a[i]]; } for(int i=1; i<=n; i++) { LL x=0,y=0; if(f[a[i]])x=Depth[f[a[i]]],Depth[a[i]]=max(Depth[a[i]],x+1); if(g[a[i]])y=Depth[g[a[i]]],Depth[a[i]]=max(Depth[a[i]],y+1); sum+=Depth[a[i]]; printf("%lld\n",sum); } return 0; }
|