【[AGC005B] Minimum Sum】 題解
阿新 • • 發佈:2021-12-02
題目連結
從1開始從小到大考慮,用set維護每個數左右的擴散範圍,然後答案為這個數的區間就是左端點個數 \(\times\) 右端點個數。
Code
// Problem: AT2060 [AGC005B] Minimum Sum // Contest: Luogu // URL: https://www.luogu.com.cn/problem/AT2060 // Memory Limit: 250 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; #define int long long inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+ (x<<3)+(ch^48);ch=getchar();}return x*f;} //#define mo //#define M //#define M struct node { int x, id; }a[200010]; int n, m, i, j, k; set<int>s; set<int>::iterator it; set<int>::iterator iw; int ans, l, r; bool cmp(node x, node y) { return x.x<y.x; } signed main() { // freopen("tiaoshi.in","r",stdin); // freopen("tiaoshi.out","w",stdout); n=read(); for(i=1; i<=n; ++i) a[i].x=read(), a[i].id=i; sort(a+1, a+n+1, cmp); s.insert(0); s.insert(n+1); for(i=1; i<=n; ++i) { // printf("> %lld %lld\n", a[i].x, a[i].id); it = s.upper_bound(a[i].id); r=*it; it--; l=*it; k=max((long long)0, r-l-1); ++l; --r; // printf("%lld %lld %lld\n", l, r, k); ans+=a[i].x*max((long long)0, (a[i].id-l+1)*(r-a[i].id+1)); s.insert(a[i].id); } printf("%lld", ans); return 0; }