KSPHERES - Editorial

Problem Link

Practice

Contest

Difficulty

Easy

Pre-requisites

Dynamic programming

Problem

Count the number of ways to construct a sequence of nested spheres

How to get 40 points

First of all, let’s note that the number of ways construct a sphere of the radii of R is equal to the product of the number of lower hemispheres of the radii of R multiplied by the number of upper hemispheres of the radii of R. Let’s call this number S[R].

Now, let’s denote the number of ways to construct a sequence of K nested spheres with the largest sphere having the radii of R by F[K][R]. Let’s take F[0][0] equal to one.

The rules for the recalculation of f[K][R] are straightfowrward: we need to pick a sequence of (K-1) spheres, where the largest sphere has the radii less than R. The number of such sequences (let’s denote it by W[K][R]) is equal to the sum of F[K-1][J] for all J < R. Now we need to add a sphere of the radii R to the end of each of these sequences. Considering that there are S[R] ways to create a sphere of the radii of R, we obtain that F[K][R] = W[K][R]*S[R].

The number of sequences of K nested spheres will clearly be equal to the sum of F[K][J] for all J between 1 and C.

In total, we need to calculate O(C2) states of F[][], and it takes O(C) to calculate each of them. So, the total complexity will be O(C3).

This solution is capable of solving the first two subtasks, but is too slow to solve the last one.

How to get 100 points

The solution’s idea remains the same.

Let’s find a way to calculate the values of F[][] in O(1) time. For achieving this, let’s note that the value of W[K][R] equals to the W[K][R-1] + F[K-1][R-1]. So now, using the old values of W[][], we can calculate the new one in O(1).

Now, since the calculation of every state runs in O(1), we get the total complexity of O(C2), which fits for our problem.

Setter’s Solution

Can be found here

Tester’s Solution

Can be found here

1 Like

It can be solved in clogn using FFT(Polynomial multiplication)…I implemented it here
https://www.codechef.com/viewsolution/8318645

But i messed up with the modulo thing…Can anyone please figure out why it is giving WA in few test cases in this code…

This one is my favorite question in the OCT15 challenge. By some examinations, I knew for a given c, we need to find the sum of product of elements in every subset of size c+1. By googling, I came across a generating function for the solution. I had never coded a polynomial multiplication before. Using a naive n^2 multiplication I was able to solve it. But, instead of finding the result modulo 10^9+7 I found modulo 10^9+9. After getting WA, I tried to come up with another logic and came up with the dynamic programming solution as given above (solving dp by myself gives a lot of pleasure :)). After solving it with dp approach, I tried debugging the first generating function approach and found my mistake. Then I got AC for that.

Thanks to the initial mistake, I solved a DP problem.

My dp approach : CodeChef: Practical coding for everyone
My other approach : CodeChef: Practical coding for everyone

4 Likes

Can anybody take a look at my solution please CodeChef: Practical coding for everyone
I used the same dynamic approach as the OP but I get a wrong answer on one of the test cases.

I suspect it maybe a miscalculation with the modulus.

Any help will be much appreciated, thanks.

I solved it without using DP.Only by Simple logic.

My code is here

Solved like ad-hoc problem.

1 Like

i am getting wa in only one subtask out of 14 .i am not able to figure out the cause.please help.
my code is here
https://www.codechef.com/viewsolution/8456023

Hello,
I am a newbie here and never played with DP or modulus thing before. So i learned about modulus from somewhere and implemented this solution. Its getting WA on some cases. I think there is some problem with my 10^9+7 implementation. Can anyone please figure it out? I would be so thankful

test cases were very weak. i tried to score 40 points with this CodeChef: Practical coding for everyone but instead got 100.

2 Likes

Can anyone tell what was the problem with my solution? Was able to pass few files of 2nd and 3rd subtask.Tried alot to get pass all the files,but i think some problem with modulo operation.Please tell me where was I missing something…here’s my solution.Would be very thankful.

I am getting WA in only one of the test cases. I am really stuck. I have tried almost everything. Somebody please help. Here’s the link to my code…
https://www.codechef.com/viewsolution/8534532

@torque (a-b)%m is NOT (a%m - b%m)%m instead it is (a%m - b%m + m)%m

Can anyone plz take a lokk at my solution, i am getting WA in just one testcase. CodeChef: Practical coding for everyone

@fkhan_iitbhu use long long int everywhere

@atulshanbhag could you please tell me the reason for use long long everywhere in fkhan_iitbhu solution.
Where his solution is getting an overflow.

This was my First DP problem. Thanks to Problem Setter, this was really an amazing problem! :slight_smile:

I tried quite a few different approaches for this problem but the first one I used is this.
https://www.codechef.com/viewsolution/8373392
I basically used the previous values to ith sequence to get the values of the (i+1)th sequence but yet couldn’t find why I was getting WA in particular cases.
Could someone please help me out?

Nice problem , it made me to think for a sol of polynomial multiplication …
which would not be possible , if i had studied DP earlier

This problem can be solved by multiplying two polynomial iteratively.
by taking 1 polynomial as (1 + a[i]x ) and other as product obtained earlier …

Here’s link to my code… CodeChef: Practical coding for everyone

@rb08
Actually I also found only FFT and I didn’t understand it. I am still trying to understand that.

For the above problem, I only needed to multiply n linear polynomials that made it a bit easy (I don’t know if I could do for higher power).

Here’s my approach.

Consider the polynomial (x-1)*(x-2)

It is equal to x^2-3x+2

For any multiplication we only need the co-efficient of the polynomial (let’s store only the co-efficient in array say coeff). Also, when we are multiplying the first polynomial with x, since it’s co-efficient is 1, the coefficients of the result doesn’t change. Only power of each term increases by 1.

Let’s write x-1 as 0x^2 + 1x - 1. When we are multiplying it with x, the result becomes
1x^2 - 1x +0. The power increases and co-efficient remains same.

When the constant factor is multiplied, the co-efficient change, not the power of each term.
(x-1)(-2) = -2x + 2 (power of each term is constant). Now after multiplication of each part, we need to add the result.

The coeff array before multiplication is {0,1,-1} //0 for x^2

After multiplying x, since the power increases, we can simply shift them to the left as
{1,-1,0} and then add the result of the second multiplication with the constant. This result has power less than the first multiplication result. So we start adding the terms starting from the second term (check below to understand).

Co-efficient after multiplication with x, {1,-1,0}

Co-efficient after multiplication with -2, {0,-2,+2}

Ignoring the first term which is always 0 for second result, and un-altered for first result, we add the remaining corresponding terms. So result is {+1,-3,+2}.

This is the basic approach. Hope you understood.

In my code, I didn’t use multiple arrays for multiplication. I used a single long array initialized to 0. The first element of the array is the co-efficient for the highest power term. (whatever the highest term is after each multiplication). I used a pointer
idx to indicate the last position of the result (co-efficient of power 0, i.e. the constant term). For each multiplication, after multiplying with x, simply increased idx by 1. The new added term is always 0 as initialized. While multiplying the constant part, we need to add the result to corresponding terms. Remember, even though we shifted the co-efficient to the left, their value didn’t change. We can re-use them for the multiplication again. See below

idx is pointing to last element. So the element before it is equal to the co-efficient of power 0 before multiplying the x. We need to multiply the constant term -2 to this co-efficient and add it to the term at idx (see it using pen and paper for better understanding). I did the following to accomplish this

coeff[idx]+=(coeff[idx-1]*constant_term)

Putting it in a loop, we get

for(int i=idx;i>0;i–) //i!=0 as 0th term is the highest power and it’s co-efficient never changes

coeff[i]+=(coeff[i-1]*constant_term)

I used modular arithmetic on this.

1 Like

I am getting 15 points and WA in some of the subtasks ,please can somebody take a look at my solution and tell me what is the problem here CodeChef: Practical coding for everyone .It would be a great help,as this is the first time I got some points in a DP question :slight_smile:

I didn’t understand why F[0][0] is taken ‘1’ and not ‘0’ in the editorial. Also what will be the base case for W[][]? Is F[0][0]=1(if it is correct) enough to solve the problem ?