[CEOI2020 D1T1 / CF1402A] 花式围栏Fancy Fence 题解

我的CEOI作战记录&题解-洛谷博客

我的CEOI作战记录&题解-cnblogs

题目链接-luogu 题目链接-Codeforces

\(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;
}
posted @ 2020-08-31 18:53  srf  阅读(412)  评论(0编辑  收藏  举报