codeforces 1037

题解:

E-trips

哎哎哎好傻逼啊

没有想到算不能的一直在想怎么算能的

太傻逼了

其实很简单

我们只需要对好友<=k的首先dfs一下给他连接着的朋友-1

然后如果小于了就递归下去

这个正确性是比较好想的

最后剩下的每个都是好友>=k个的并且都是这之间的

我们把他们都选了就可以了

这样不支持连边但是可以删边,所以倒着做就可以了

F - Maximum Reduction

大水题

会发现要求的长度为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; 
}

 

posted @ 2018-09-03 21:32  尹吴潇  阅读(266)  评论(0编辑  收藏  举报