[CEOI2020 D1T1 / CF1402A] 花式围栏Fancy Fence 题解
记\(f(x) = \frac{x(x+1)}{2}.\)
不难发现答案为\(\sum\limits_{i=1}^n f(w_i) * f(h_i)+\sum\limits_{1\leq l<r\leq n} w_lw_rf(\min\limits_{i=l}^r(h_i))\)
用单调栈优化即可\(.\)
代码\(:\)
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 100050,P = 1e9 + 7;
int n,a[N],b[N],L[N],R[N],stk[N],_,ans;
inline bool cmp(int x,int y){ return a[x] == a[y] ? x < y : a[x] < a[y]; }
inline int F(int n){ return (LL)n * (n+1) / 2 % P; }
inline int calc(int l,int r){ return (b[r] - b[l-1] + P) % P; }
int main(){
int i;
cin >> n;
for (i = 1; i <= n; ++i) cin >> a[i];
for (i = 1; i <= n; ++i) cin >> b[i],b[i] = (b[i] + b[i-1]) % P;
stk[_=1] = 1; for (i = 2; i <= n; ++i){ while (_ && cmp(i,stk[_])) R[stk[_]] = i-1,--_; stk[++_] = i; }
while (_) R[stk[_]] = n,--_;
stk[_=1] = n; for (i = n-1; i ; --i){ while (_ && cmp(i,stk[_])) L[stk[_]] = i+1,--_; stk[++_] = i; }
while (_) L[stk[_]] = 1,--_;
for (i = 1; i <= n; ++i){
ans = (ans + (LL)F(calc(i,i)) * F(a[i]) % P) % P;
ans = (ans + (LL)F(a[i]) * calc(L[i],i-1) % P * calc(i+1,R[i]) % P) % P;
ans = (ans + (LL)F(a[i]) * calc(i,i) % P * calc(i+1,R[i]) % P) % P;
ans = (ans + (LL)F(a[i]) * calc(L[i],i-1) % P * calc(i,i) % P) % P;
}
cout << ans << '\n';
return 0;
}