Pagini recente » iconcurs22 | Cod sursa (job #1301029) | Cod sursa (job #1055664) | Cod sursa (job #2284702) | Cod sursa (job #486200)
Cod sursa(job #486200)
#include<fstream>
#include<set>
#include<cassert>
using namespace std;
const char iname[]="euro.in";
const char oname[]="euro.out";
const int maxn=360000;
ifstream f(iname);
ofstream g(oname);
long long a[maxn],s[maxn],maxt,rez,dp[maxn],zi[maxn],ok,x;
int i,n,t;
struct maxv
{
bool operator()(const int &x,const int &y)
{
long long v=dp[x]-s[x]*i-dp[y]+s[y]*i;
if(v==0)
return s[x]>s[y];
return v<0;
}
};
struct zile
{
bool operator()(const int &x,const int &y)
{
return zi[x]<zi[y];
}
};
set<int,zile> R;
set<int,maxv> S;
int main()
{
f>>n>>t;
for(i=1;i<=n;++i)
f>>a[i],s[i]=s[i-1]+a[i];
maxt=rez=0;
S.insert(0);
for(i=1;i<=n;++i)
{
set<int,maxv>::iterator it,jt;
x=*(S.rbegin());
dp[i]=dp[x]+(s[i]-s[x])*i-t;
it=S.insert(i).first;
ok=1;
//Trebuie eliminat :?
jt=it;
jt++;
if(jt!=S.end())
if(s[*it]>=s[*jt])
{
S.erase(it);
ok=0;
}
//daca nu
if(ok)
{
//scaotem ratia
//scoate alea cu crestere mai mica
while(it!=S.begin())
{
jt=it;
jt--;
if(s[*jt]>=s[i])
R.erase(*jt),S.erase(jt);
else
break;
}
//adaugam ratia de crestere inapoi
it=S.find(i);
if(it!=S.begin())
{
jt=it;
jt--;
R.erase(*jt);
x=dp[*it]-dp[*jt];
x=x/(s[*it]-s[*jt])+1;
zi[*jt]=x;
// assert(x>i);
R.insert(*jt);
if(S.find(*jt)==S.end())
assert(0);
}
//adaugam ratia de crestere inainte
jt=it;
++it;
if(it!=S.end())
{
x=dp[*it]-dp[*jt];
x=x/(s[*it]-s[*jt])+1;
// assert(x>i);
R.erase(*jt);
zi[*jt]=x;
R.insert(*jt);
// assert(S.find(*jt)!=S.end());
}
}
// for(set<int,maxv>::iterator it=S.begin();it!=S.end();++it)
// fprintf(stderr,"%d ",*it);
// printf("\n");
while(R.size()>0&&zi[*R.begin()]<=i+1)
{
x=*R.begin();
R.erase(x);
it=S.find(x);
if(it==S.end())
continue;
jt=it;
++jt;
if(dp[*it]-s[*it]*(i+1)>=dp[*jt]-s[*jt]*(i+1))
R.erase(*jt),S.erase(jt);
//adaugam ratia in fata
jt=it;
++it;
if(it==S.end())
continue;
x=dp[*it]-dp[*jt];
x=x/(s[*it]-s[*jt])+1;
// if(x<=i)
// assert(s[*it]>s[*jt]);
zi[*jt]=x;
R.insert(*jt);
}
}
g<<dp[n]<<"\n";
}