Codeforces1037F Maximum Reduction 【单调栈】
题目分析:
没啥好说的,会单调栈就会做。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1005000; 5 const int mod = 1000000007; 6 7 int n,k; 8 int pre[maxn],suf[maxn],a[maxn]; 9 10 stack <int> sta; 11 void getpre(){ 12 for(int i=n-1;i>=0;i--){ 13 while(!sta.empty()&&a[sta.top()]<=a[i])pre[sta.top()]=i+1,sta.pop(); 14 sta.push(i); 15 } 16 while(!sta.empty()) pre[sta.top()]=0,sta.pop(); 17 } 18 void getsuf(){ 19 for(int i=0;i<n;i++){ 20 while(!sta.empty()&&a[sta.top()]<a[i])suf[sta.top()]=i-1,sta.pop(); 21 sta.push(i); 22 } 23 while(!sta.empty()) suf[sta.top()]=n-1,sta.pop(); 24 } 25 26 void read(){ 27 scanf("%d%d",&n,&k); 28 for(int i=0;i<n;i++) scanf("%d",&a[i]); 29 getpre(); getsuf(); 30 } 31 32 int getsize(int len){ 33 int p = (len-1)/k; 34 int ans = (1ll*len*p%mod-1ll*(1+p)*p/2%mod*k%mod+mod)%mod; 35 return ans; 36 } 37 38 void work(){ 39 int ans = 0;k--; 40 for(int i=0;i<n;i++){ 41 int tot = getsize(suf[i]-pre[i]+1); 42 tot -= getsize(suf[i]-i); tot += mod; tot %= mod; 43 tot -= getsize(i-pre[i]); tot += mod; tot %= mod; 44 ans += 1ll*tot*a[i]%mod; ans %= mod; 45 } 46 printf("%d",ans); 47 } 48 49 int main(){ 50 read(); 51 work(); 52 return 0; 53 }