codeforces 1037
题解:
E-trips
哎哎哎好傻逼啊
没有想到算不能的一直在想怎么算能的
太傻逼了
其实很简单
我们只需要对好友<=k的首先dfs一下给他连接着的朋友-1
然后如果小于了就递归下去
这个正确性是比较好想的
最后剩下的每个都是好友>=k个的并且都是这之间的
我们把他们都选了就可以了
这样不支持连边但是可以删边,所以倒着做就可以了
大水题
会发现要求的长度为k,2k-1,3k-2,4k-3的最大值
单调栈维护前驱后继
然后前缀和优化一下求答案就完了
#include <bits/stdc++.h> using namespace std; #define ll long long #define rint register int #define IL inline #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) #define mid ((h+t)>>1) const int mo=1e9+7; const int N=2e6; ll a[N],sum[N],ans; int nxt[N],pre[N]; struct re{ int a,b; }ve[N]; int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); int n,m; cin>>n>>m; rep(i,1,n) cin>>a[i]; int k=0; rep(i,1,n) { while (m*k-k+1<=i) k++; sum[i]=(sum[i-1]+k-1)%mo; } int t=0; rep(i,1,n) { while (t&&ve[t].a<a[i]) { nxt[ve[t].b]=i-1; t--; } t++; ve[t].a=a[i]; ve[t].b=i; } while (t) { nxt[ve[t].b]=n; t--; } dep(i,n,1) { while (t&&ve[t].a<=a[i]) { pre[ve[t].b]=i+1; t--; } t++; ve[t].a=a[i]; ve[t].b=i; } while (t) { pre[ve[t].b]=1; t--; } rep(i,1,n) { ans+=(sum[nxt[i]-pre[i]+1]-sum[nxt[i]-i+1-1]-sum[i-pre[i]+1-1])*a[i]; ans%=mo; } cout<<(ans+mo)%mo<<endl; return 0; }