Reputation: 19
I am trying to solve this https://codeforces.com/problemset/problem/2035/D codeforces problem. I understand the logic and implementation, but I guess I am failing a modular arithmetic. Here is my code:
ll modAdd(ll a, ll b, ll mod) {
return (a % mod + b % mod) % mod;
}
ll modSub(ll a, ll b, ll mod) {
return ((a - b)%mod + mod) % mod; // Adding mod ensures non-negative result
}
// Function for modular multiplication
ll modMul(ll a, ll b, ll mod) {
return (1LL * (a % mod) * (b % mod)) % mod; // 1LL ensures no overflow for large numbers
}
// Function for modular exponentiation
ll modExp(ll base, ll exp, ll mod) {
ll result = 1;
base = base % mod;
while (exp > 0) {
if (exp % 2 == 1) {
result = modMul(result, base, mod);
}
base = modMul(base, base, mod);
exp /= 2;
}
return result;
}
class Compare {
public:
bool operator()(pair<ll, ll> below, pair<ll, ll> above)
{
return below.first > above.first;
}
};
void solve() {
ll n;
cin>>n;
vector<ll> v(n);
for(ll i = 0; i<n; i++)cin>>v[i];
priority_queue<pair<ll, ll>, vector<pair<ll,ll>>, Compare> pq;
ll sum = 0;
vector<ll> ans;
for(ll i = 0; i<n; i++){
ll sa = v[i];
ll cnt = 0;
while(sa % 2 == 0){
sa = sa / 2;
cnt++;
}
while(!pq.empty() && pq.top().first <= v[i]){
ll val = pq.top().first;
cnt+=pq.top().second;
val = modMul(val, modExp(2, pq.top().second, MOD)-1, MOD);
sum = modSub(sum, val, MOD);
//sum = modAdd(pq.top().first, sum, MOD);
for(ll j = 0; j<pq.top().second; j++){
v[i] = modMul(v[i], 2, MOD);
}
pq.pop();
}
sum =modAdd(v[i], sum, MOD);
pq.push({sa , cnt});
cout<<sum<<" ";
}
cout<<endl;
}
Explanation:
Variable sa -> stripped 'a' is obtained by dividing the array element by 2 until it can't, such that it doesn't have factor 2.
Variable cnt -> number of times 'a' can be divided by 2
Kept a priority queue of these 2 as a pair.
Whenever an array element is greater than or equal to sa, I will multiply that element by 2^cnt, because doing this will increase the sum, by this way I am propogating the 2's power to the element that will give be largest sum when multiplied with.
Fails on test 3, I suspect that it is because of modular subtraction, but not sure what actually is causing the error.
Upvotes: -1
Views: 61
Reputation: 19
Found what was wrong, it was just comparison in the while loop
while(!pq.empty() && **pq.top().first <= v[i]**)
Here, the value of v[i]
can get smaller than first value of priority queue, because of using mod
on v[i]
, to get the correct answer, I needed to compare that with complete value without modding it
Changed it to this
while(!pq.empty() && (cnt > 32 || pq.top().first <= sa*(1ll << cnt)))
And it worked, though priority queue gave a TLE.
Upvotes: 1