zoukankan      html  css  js  c++  java
  • [CF1037F]Maximum Reduction

    题意

    https://codeforces.com/contest/1037/problem/F


     

    思考

    摘自一种比较有趣的做法。我们对序列进行分治,每次统计跨过mid的区间的贡献。其正确性是保证的:每个区间只会对应到一个mid。对于左区间,算出它的后缀最大值。

    接下来从左到右枚举右区间的每一个点。对于点$i$,右端点在它上面的区间的跨度是$k-1$的。因此除了最大值相同的从右到左的block个区间,剩下的贡献要通过左区间跨度为(k-1)的(后缀最大值)的前缀和求出。

    代码很少,但细节很多。虽然复杂度为$O(nlogn)$,但不失为解决这一类问题的优秀算法。


     

    代码

     1 #include<bits/stdc++.h>
     2 #define mod 1000000007
     3 using namespace std;
     4 typedef long long int ll;
     5 const int maxn=1E6+5;
     6 int n,k;
     7 ll ans,a[maxn],maxx[maxn],sum[maxn];
     8 inline ll max(ll x,ll y)
     9 {
    10     return x>y?x:y;
    11 }
    12 void solve(int l,int r)
    13 {
    14     if(r-l+1<k)
    15         return;
    16     int mid=(l+r)>>1;
    17     maxx[mid]=a[mid];
    18     for(int i=mid-1;i>=l;--i)
    19         maxx[i]=max(maxx[i+1],a[i]);
    20     sum[l-1]=0;
    21     sum[l]=maxx[l];
    22     for(int i=l+1;i<=mid;++i)
    23     {
    24         sum[i]=0;
    25         int pos=i-k+1;
    26         if(pos>=l)
    27             sum[i]=sum[pos];
    28         sum[i]=(sum[i]+maxx[i])%mod;
    29     }
    30     ll now=a[mid+1];
    31     for(int i=mid+1,j=mid;i<=r;++i,now=max(now,a[i]))
    32     {
    33         if(i-l+1<k)
    34             continue;
    35         while(j>=l&&maxx[j]<now)
    36             --j;
    37         int len=i-j+1;
    38         int block=(len-2)/(k-1);
    39         int out=block+1;
    40         block-=(i-mid-1)/(k-1);
    41         ans=(ans+block*now%mod+sum[max(l-1,i-out*(k-1))])%mod;
    42     }
    43     solve(l,mid),solve(mid+1,r);
    44 }
    45 int main()
    46 {
    47     ios::sync_with_stdio(false);
    48     cin>>n>>k;
    49     for(int i=1;i<=n;++i)
    50         cin>>a[i];
    51     solve(1,n);
    52     cout<<ans<<endl;
    53     return 0;
    54 }
    View Code
  • 相关阅读:
    263邮箱配置告警发件配置
    交换机日期时间设置
    【Switch】- 配置日志文件输出syslog信息
    网络设备断电注意事项
    H3C交换机保存机制
    Docker学习笔记
    小型网络组网模型讲解
    Linux下管理员强行踢出用户的命令使用方法
    Linux SNMP 监控一些常用OID
    MySQL解决方案
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/11409383.html
Copyright © 2011-2022 走看看