1. 程式人生 > >Codeforces 1037F. Maximum Reduction

Codeforces 1037F. Maximum Reduction

tput style () force signed cout div else cst

總感覺我這種做法會T,一直沒寫,看了其他人的題解也是這樣,,,就果斷寫了,,可能數據不太深,或者玄學復雜度

題意即求xk-1長度的所有區間的最大值的和,對每一個i(數組下邊),他對答案的貢獻數量就是在以ar[i]為最大值的最大子區間中所有符合條件的區間數量

求ar[i]的作用區間,即,求最小的l,對於x>=l&&x<i,ar[x]<=ar[i];求最大的r,對於k<=r&&k>i,ar[k]<ar[i];則ar[i]的作用區間為[l,r];我代碼中的ar[i]的作用區間為(pre[i],nex[i])

然後遍歷i左右中更小的區間,求ar[i]對答案的貢獻數量即可,代碼思路應該很清晰

#include<iostream>
#include<cstdio> 
#include<cmath>
#include<queue>
#include<vector>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<fstream>
#include<cstdlib>
#include<ctime>
#include
<list> #include<climits> #include<bitset> using namespace std; #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("input.in", "r", stdin);freopen("output.in", "w", stdout); #define left asfdasdasdfasdfsdfasfsdfasfdas1 #define tan asfdasdasdfasdfasfdfasfsdfasfdas typedef
long long ll; typedef unsigned int un; const int desll[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; const ll mod=1e9+7; const int maxn=2e6+7; const int maxm=1e9+7; const double eps=1e-4; int m,n,k; int ar[maxn]; int pre[maxn],nex[maxn]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&ar[i]); pre[1]=0; for(int i=2;i<=n;i++){ int ins=i-1; while(ins>0 && ar[ins]<ar[i])ins=pre[ins]; pre[i]=ins; } nex[n]=n+1; for(int i=n-1;i>0;i--){ int ins=i+1; while(ins<=n && ar[ins]<=ar[i])ins=nex[ins]; nex[i]=ins; } //for(int i=1;i<=n;i++)cout<<pre[i]<<" ";cout<<endl; //for(int i=1;i<=n;i++)cout<<nex[i]<<" ";cout<<endl; ll ans=0; for(int i=1;i<=n;i++){ int l=pre[i],r=nex[i]; ll a,b; if(i-l<r-i){ for(int x=l+1;x<=i;x++){//x為符合條件的區間的起始點 a=(i-x+1-1+m-2)/(m-1);//a為包含i的區間中最少的(m-1)段數 a=max(a,1LL); b=(r-x-1)/(m-1);//b為以r-1為區間終點,可以貢獻的最多(m-1)段數 ///cout<<"x = "<<x<<" "<<a<<" "<<b<<endl; if(b>=a){ ans = (ans + (b-a+1)*ar[i]%mod)%mod; } } } else{ for(int x=i;x<r;x++){ a=(x-i+1-1+m-2)/(m-1); a=max(a,1LL); b=(x-l-1)/(m-1); //cout<<"x = "<<x<<" "<<a<<" "<<b<<endl; if(b>=a){ ans = (ans + (b-a+1)*ar[i]%mod)%mod; } } } //cout<<i<<" "<<ans<<" "<<a<<" "<<b<<endl; } printf("%I64d\n",ans); return 0; }

Codeforces 1037F. Maximum Reduction