Author : Balaji_31
Required Knowledge : Binary Search
Time Complexity :
Editorialist : Balaji_31
This problem asks for the minimum daily collection amount, , that allows the Avengers to secure at least half the total Quantum Energy Units. must be a multiple of . The process is a daily cycle: the Avengers collect units, and then Thanos destroys percent of the remaining amount.
To find the smallest valid , we can use binary search. Instead of searching on itself, we search for the smallest multiplier such that is a successful strategy.
For any given , we run a simulation. We track the Avengers collected total and the remaining uncollected units. Each day in the simulation, we add to the Avengers' total and subtract it from the remaining pile. Then, we reduce the remaining pile by (rounding down) to simulate Thanos's attack. This simulation continues until the remaining units hit zero.
If the simulation ends with the Avengers total being at least half of the initial amount, then that is a valid (though perhaps not minimal) solution.
The binary search uses this simulation as its check:
If a test (from the middle of our search range) is successful, we know a solution exists, so we try a smaller by narrowing the search to the lower half.
If fails, it was too small, so we must search the upper half for a larger .
This continues until the search converges on the smallest possible multiple of that guarantees the Avengers meet their goal. The simulation is fast because the remaining units decrease geometrically, leading to an efficient overall solution.
Here's the time complexity analysis for that exact approach:
Simulation: The check function is fast. Since is reduced by (where ) each night, it shrinks geometrically. This takes time, not .
Binary Search: We search for a multiplier in a range of size . This takes steps.
Total: We run the simulation inside each binary search step.
The time complexity per test case is , which is roughly .
For test cases, the total time is . Fast enough.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define vll vector<ll>
#define pb push_back
#define mp make_pair
#define endl "\n"
#define mod 1000000007
#define tot(a) a.begin(),a.end()
#define minii *min_element
#define maxii *max_element
void solve()
{
ll n,m,p;
cin>>n>>m>>p;
ll l=1,r=(n/m)+1,mid;
ll ans=(ll)(1e18);
while(l<=r)
{
mid=(l+r)/2;
ll val=mid*m;
ll nn=n;
ll s=0;
while(nn)
{
if(nn<val)
{
s+=nn;
nn=0;
}
else
{
nn-=val;
s+=val;
}
nn=(nn-(p*nn)/100);
}
if(s>=(n+1)/(2LL))
{
ans=min(ans,val);
r=mid-1;
}
else
{
l=mid+1;
}
}
cout<<ans<<endl;
}
int main()
{
ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
ll t;cin>>t;while(t--)
solve();
return 0;
}
def solve():
n, m, p = map(int, input().split())
l, r = 1, (n // m) + 1
ans = int(1e18)
while l <= r:
mid = (l + r) // 2
val = mid * m
nn = n
s = 0
while nn:
if nn < val:
s += nn
nn = 0
else:
nn -= val
s += val
nn = nn - (p * nn) // 100
if s >= (n + 1) // 2:
ans = min(ans, val)
r = mid - 1
else:
l = mid + 1
print(ans)
t = int(input())
for _ in range(t):
solve()