P6503 [COCI2010-2011#3] DIFERENCIJA 題解
阿新 • • 發佈:2020-10-27
Link
P6503 [COCI2010-2011#3] DIFERENCIJA
Solve
這道題和SP10622相類似
我們可以把最大值和最小值分開來考慮,於是對於每個\(a[i]\),我們統計出\(a[i]\)作為最大值和最小值的範圍,從而算出\(a[i]\)對答案的貢獻
\(pre\underline{~}min\)表示前面第一個比\(a[i]\)小的,\(nxt\underline{~}min\)表示後面第一個比\(a[i]小的\),那麼\(a[i]\)作為\(max\)的範圍就是\(pre\underline{~}min+1~nxt\underline{~}min-1\),\(pre\)和\(nxt\)
計算\(min\)的時候同理
Code
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=300005,INF=1<<30; int N,pre_min[maxn],pre_max[maxn],nxt_min[maxn],nxt_max[maxn],top,c[maxn]; LL ans; struct AS{ int x,id; }a[maxn],p[maxn]; inline int read(){ int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar(); return ret*f; } int main(){ freopen("diferencija.in","r",stdin); freopen("diferencija.out","w",stdout); N=read(); for(int i=1;i<=N;i++)a[i].x=read(),a[i].id=i; p[top=1]=(AS){0,0};for(int i=1;i<=N;i++){while(top>0&&p[top].x>=a[i].x)top--;pre_min[i]=p[top].id;p[++top]=a[i];} p[top=1]=(AS){INF,0};for(int i=1;i<=N;i++){while(top>0&&p[top].x<=a[i].x)top--;pre_max[i]=p[top].id;p[++top]=a[i];} p[top=1]=(AS){0,N+1};for(int i=N;i;i--){while(top>0&&p[top].x>a[i].x)top--;nxt_min[i]=p[top].id;p[++top]=a[i];} p[top=1]=(AS){INF,N+1};for(int i=N;i;i--){while(top>0&&p[top].x<a[i].x)top--;nxt_max[i]=p[top].id;p[++top]=a[i];} for(int i=1;i<=N;i++){ans+=((LL)(nxt_max[i]-i)*(i-pre_max[i])-(LL)(nxt_min[i]-i)*(i-pre_min[i]))*(LL)a[i].x;} printf("%lld\n",ans); return 0; }