Problem name: Feast
Topic: Array
Tags: Sorting, Prefix sum
Level: Hard
Language used: C++
Problem Statement:
Alice has decided to visit a restaurant with a circular food conveyor belt. The belt has
a circumference of C meters, and guests are seated around the outer edge of the
belt, unable to step inside.
On the belt, there are N different dishes at specific positions. The distance from
Alice's starting point to the location of the i-th dish is Xi meters, and the dish provides
Vi kilocalories of energy.
Alice can walk along the belt to grab dishes, consuming the calories each one offers.
However, for every meter she walks, she burns 1 kilocalorie. She can stop and leave
the belt from any point once she is satisfied, without needing to return to her starting
position.
Your task is to help Alice maximize her net energy gain. How much nutrition can Alice
collect after deducting the calories she burns walking?
Input Format:
The first line of each test case contains two integers N and C — the number of
dishes on the belt and circumference of the belt, respectively.
The next N lines contains Xi and Vi – the distance from starting point to i-th dish and
the amount of energy in kilocalories the dish provides, respectively.
Output Format:
For each test case, output on a new line the maximum amount of nutrition Alice can
collect after deducting the calories she burns walking.
Constraints:
1<=N<=10^5
2<=C<=10^14
1<X1<X2< …. <XN<C
1<=Vi<=10^9
Sample Input 1:
3 20
2 80
9 120
16 1
Sample Output 1:
191
Explanation for Sample case 1:
There are three dishe on the counter with a circumference of 20 meters. If she walks
two meters clockwise from the initial place, she can eat a dish of 80 kilocalories. If
she walks seven more meters clockwise, she can eat a dish of 120 kilocalories. If
she leaves now, the total nutrition taken in is 200 kilocalories, and the total energy
consumed is 9 kilocalories, thus she can take in 191 kilocalories on balance, which is
the largest possible value.
Sample Input 2:
3 20
2 80
91
16 120
Sample Output 2:
192
Explanation for Sample case 2:
The second and third dish have been swapped. Again, if she walks two meters
clockwise from the initial place, she can eat a dish of 80 kilocalories. If she walks six
more meters counterclockwise this time, she can eat a dish of 120 kilocalories. If she
leaves now, the total nutrition taken in is 200 kilocalories, and the total energy
consumed is 88 kilocalories, thus she can take in 192 kilocalories on balance, which
is the largest possible value.
Code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=100005,LG=17;
int n;
ll C;
ll x[N],a[N],asum[N],atot[N];
ll init_val[N];
ll y[N],b[N],bsum[N];
struct ST{
ll s[N][22];
void init()
{
for(int i=1;i<=n;i++)
s[i][0]=init_val[i];
for(int j=1;j<=LG;j++)
for(int i=1;i+(1<<j)<=n;i++)
s[i][j]=max(s[i][j-1],s[i+(1<<(j-1))][j-1]);
}
ll query(int l,int r)
{
if(l>r) return 0ll;
int k=(int)floor(log(r-l+1)/log(2));
return max(max(s[l][k],s[r-(1<<k)+1][k]),0ll);
}
};
ST c1,c2;
int main()
{
scanf("%d%lld",&n,&C);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&x[i],&a[i]);
y[n-i+1]=C-x[i];
b[n-i+1]=a[i];
}
for(int i=1;i<=n;i++) bsum[i]=bsum[i-1]+b[i];
for(int i=1;i<=n;i++)
{
asum[i]=asum[i-1]+a[i];
atot[i]=asum[i]-x[i];
}
for(int i=1;i<=n;i++)
init_val[i]=bsum[i]-y[i];
c1.init();
for(int i=1;i<=n;i++)
init_val[i]=bsum[i]-y[i]-y[i];
c2.init();
ll ans=0;
for(int i=1;i<=n;i++) ans=max(ans,atot[i]);
for(int i=1;i<=n;i++) ans=max(ans,bsum[i]-y[i]);
ll ans1,ans2;
for(int i=1;i<=n;i++)
{
ans1=c1.query(1,n-i)+asum[i]-x[i]-x[i];
ans2=c2.query(1,n-i)+asum[i]-x[i];
ans=max(ans,max(ans1,ans2));
}
printf("%lld",ans);
return 0;
}
Compiler link (C++)
Compiler link (python)
Compiler link (java)