Блог пользователя CapTa1nnn

Автор CapTa1nnn, 19 месяцев назад, По-английски

Hi guys. To day i meet a problem that : give you integer t is number of test case (t <= 10) each line have an interger n ( n <= 1e6) , Count the number of ways to choose a distinct (at least 1) set of numbers (elements in the ascending set) such that they form an arithmetic progression.

example : if n = 3 , the answer is 7 : (1,2,3,12,13,23,123)

  • Проголосовать: нравится
  • +22
  • Проголосовать: не нравится

»
19 месяцев назад, # |
Rev. 8   Проголосовать: нравится +26 Проголосовать: не нравится

A solution that runs in $$$O(t\cdot n)$$$ should easily be fast enough.

First of all, there are $$$n$$$ ways of choosing exactly $$$1$$$ value. We can add this to the answer. Now, every remaining arithmetic progression will have at least $$$2$$$ values.

Recall that an arithmeric progression has a constant difference of consecutive elements, let's call it $$$d$$$. $$$d$$$ can have any value between $$$1$$$ and $$$n - 1$$$. If we can calculate the number of arithmetic progressions for each value of $$$d$$$, we can sum those up and calculate the answer on $$$O(n)$$$.

How to solve the problem for each $$$d$$$? Let's consider an example case $$$n = 10$$$, $$$d = 3$$$. For two numbers to have a difference of $$$d$$$, they must be equivalent modulo $$$d$$$ (i.e. they have the same remainder when divided by $$$d$$$). Let's group the $$$n = 10$$$ numbers based on their remainder modulo $$$d = 3$$$ in ascending order:

0 mod 3: 3 6 9
1 mod 3: 1 4 7 10
2 mod 3: 2 5 8

Now we have $$$d = 3$$$ different arrays of integers. Notice that any continuous subarray of length $$$> 1$$$ of any one of these arrays is an arithmetic progression with $$$d = 3$$$. Also notice, that every possible arithmetic progression of values $$$1..10$$$ with $$$d = 3$$$ is a subarray of length $$$> 1$$$ of one of these arrays. This means that the number of arithmetic progressions with $$$d = 3$$$ is equal to the number of subarrays of length $$$> 1$$$ of these arrays.

How can we calculate the number of subarrays of length $$$> 1$$$ of these arrays? Recall that an array of length $$$k$$$ has exactly $$$\frac{k(k+1)}{2}$$$ subarrays, exactly $$$k$$$ of which have length $$$1$$$. Thus, the number of subarrays of length $$$> 1$$$ is $$$\frac{k(k+1)}{2} - k = \frac{k(k+1)}{2} - \frac{2k}{2} = \frac{k(k+1) - 2k}{2} = \frac{k(k + 1 - 2)}{2}= \frac{k(k-1)}{2}$$$.

Each value of $$$d$$$ creates $$$d$$$ different arrays, we can't just iterate over all of them. How can we find the number of subarrays in all of them efficiently (for fixed $$$d$$$)?

Notice that the integers $$$1, 2, 3, \dots d$$$ all have different remainders modulo $$$d$$$. Thus, they belong to different arrays. The same applies for integers $$$d + 1, d + 2, d + 3, \dots 2d$$$, integers $$$2d + 1, 2d + 2, 2d + 3, \dots 3d$$$ up to $$$(k-1)d + 1, (k-1)d + 2, (k-1)d + 3, \dots kd$$$, where $$$k$$$ is the largest integer satisfying $$$kd \le n$$$. We can see that

$$$kd \le n \Leftrightarrow k \le \frac{n}{d}$$$

The largest integer satisfying this is $$$k = \left\lfloor\frac{n}{d}\right\rfloor$$$. This means that all $$$d$$$ arrays contain at least $$$\left\lfloor\frac{n}{d}\right\rfloor$$$ integers. The remaining $$$n \bmod d$$$ integers all have different remainders modulo $$$d$$$ meaning that they belong to different arrays. This means that $$$n \bmod d$$$ of the $$$d$$$ arrays actually contain $$$\left\lfloor\frac{n}{d}\right\rfloor + 1$$$ integers, and the remaining $$$d - (n \bmod d)$$$ arrays contain $$$\left\lfloor\frac{n}{d}\right\rfloor$$$ integers.

Thus, the number of subarrays of the arrays for a given $$$d$$$ (which equals the number of arithmetic progressions with consecutive difference $$$d$$$) is

$$$\displaystyle(n \bmod d) \cdot \frac{\left(\left\lfloor\frac{n}{d}\right\rfloor + 1\right)\left(\left\lfloor\frac{n}{d}\right\rfloor + 1 - 1\right)}{2} + (d - n \bmod d) \cdot \frac{\left\lfloor\frac{n}{d}\right\rfloor\left(\left\lfloor\frac{n}{d}\right\rfloor - 1\right)}{2}$$$

$$$ = \displaystyle(n \bmod d) \cdot \frac{\left(\left\lfloor\frac{n}{d}\right\rfloor + 1\right)\left\lfloor\frac{n}{d}\right\rfloor}{2} + (d - n \bmod d) \cdot \frac{\left\lfloor\frac{n}{d}\right\rfloor\left(\left\lfloor\frac{n}{d}\right\rfloor - 1\right)}{2}$$$

$$$ = \displaystyle\frac{(n \bmod d)\left\lfloor\frac{n}{d}\right\rfloor\left(\left\lfloor\frac{n}{d}\right\rfloor + 1\right) + (d - n \bmod d)\left\lfloor\frac{n}{d}\right\rfloor\left(\left\lfloor\frac{n}{d}\right\rfloor - 1\right)}{2}$$$

And the answer to the whole problem is $$$n + \displaystyle\sum_{d=1}^{n-1}\frac{(n \bmod d)\left\lfloor\frac{n}{d}\right\rfloor\left(\left\lfloor\frac{n}{d}\right\rfloor + 1\right) + (d - n \bmod d)\left\lfloor\frac{n}{d}\right\rfloor\left(\left\lfloor\frac{n}{d}\right\rfloor - 1\right)}{2}$$$

Please note that we don't need to worry about arrays of length $$$1$$$ or $$$0$$$ messing up our calculations, since the number of subarrays $$$\frac{k(k-1)}{2}$$$ gives the correct answer of $$$0$$$ in both cases.

»
19 месяцев назад, # |
Rev. 2   Проголосовать: нравится +41 Проголосовать: не нравится

I am going to refer to "Arithmetic Sequence" here as "AS"

First, handling AS of size $$$1$$$, obviously the answer is $$$N$$$, as there are $$$N$$$ single elements

Now, for any AS $$$T$$$ of Length $$$ ≥ 2$$$, it can be uniquely determined by 3 values, $$$A,n,d$$$, where $$$A$$$ is the value first term in the sequence $$$(T_0)$$$, $$$d$$$ is the common difference $$$(T_{i+1} - T_i)$$$, and $$$n+1$$$ is the number of terms in the AS $$$(T_n$$$ is the last term $$$)$$$

In your problem, the AS must satisfy two conditions :

  • The AS is ascending, so $$$d>0$$$

  • The elements are integers that belong to the interval $$$[1,N]$$$,so $$$1≤A≤N$$$ and $$$1≤T_n≤N$$$ (note that $$$n+1$$$ here denotes the length of the AS, while $$$N$$$ denotes the input in your problem)

Imagine we are brute forcing on $$$A$$$ and trying to find the summation over each answer for a specific $$$A$$$

$$$T_n$$$ is equivalent to $$$A+dn$$$, since $$$A,d,n≥1$$$, we only need to solve for the number of ways to choose $$$d,n$$$ such that $$$A+dn≤N$$$, or more precisely $$$dn≤N-A$$$

Now we have reduced our problem to this problem :

Given an integer $$$K$$$, find the number of ways to choose two integers $$$x,y$$$ $$$(1≤x,y≤K)$$$ such that $$$xy≤K$$$

There are two ways to approach this problem, one will lead to an $$$O(\sqrt n)$$$ per test case, and another one will be $$$O(n\log \log n)$$$ preprocessing and $$$O(1)$$$ per test case, since $$$N≤10^6$$$ I am going to explain the $$$O(n\log \log n)$$$ solution :

Let the number of ways to choose two integers $$$x,y$$$ $$$(1≤x,y≤Z)$$$ such that $$$xy=Z$$$ be $$$d(Z)$$$, we can see that this is actually equivalent to the number of divisors of $$$Z$$$, The reason is for every valid number $$$x$$$ we choose, there is going to be a unique $$$y$$$ such that $$$xy=Z$$$, OF course valid $$$x$$$ can only be a divisor of $$$Z$$$ (because $$$Z$$$ is a multiple of $$$x$$$)

Now, we can see that the solution to the problem above (with $$$K$$$) is equal to $$$\displaystyle\sum\limits_{Z=1}^{K}d(Z)$$$

And the solution to the original problem is equal to $$$\displaystyle\sum\limits_{A=1}^{N}\sum\limits_{Z=1}^{N-A}d(Z) = \sum\limits_{i=0}^{N-1}\sum\limits_{Z=1}^{i}d(Z)$$$ ($$$N-A$$$ here is donated as $$$i$$$)

So the answer turns out to be a double prefix sum on the array/function $$$d$$$ till $$$N-1$$$, this can be easily precalculated in $$$O(n)$$$ if we already have array $$$d$$$, and it can be easily calculated in $$$O(n\log \log n)$$$ by using prime factorization to find number of divisors of each $$$Z$$$ $$$(1≤Z≤10^6)$$$

If you need any help or clarifications regarding some details feel free to ask

  • »
    »
    19 месяцев назад, # ^ |
      Проголосовать: нравится +15 Проголосовать: не нравится

    First thank for your help so i can solve with N<= 1e6 but when i try to think with O(sqrt(n)) have no idea . Can you tell me more about it. Thank you very muchh

    • »
      »
      »
      19 месяцев назад, # ^ |
      Rev. 8   Проголосовать: нравится +32 Проголосовать: не нравится

      You are welcome ^^

      $$$\sqrt n$$$ here is going to be treated as the floored square root of $$$n$$$ for simplicity

      Regarding the $$$O(\sqrt n)$$$ approach, here is an interesting fact : $$$\displaystyle\sum\limits_{i=1}^{n}d(i) = \sum\limits_{x=1}^{n}\lfloor{\frac{n}{x}}\rfloor$$$

      The reason for this is for each divisor $$$x$$$ , we find how many numbers $$$\le n$$$ which have $$$x$$$ as a divisor, their count is equal to the number of multiples of $$$x$$$ which are $$$\le n$$$, they are equal to $$$\lfloor{\frac{n}{x}}\rfloor$$$, so we add the contributions of all divisors to the answer

      I am going to state three facts about $$$\lfloor{\frac{n}{i}}\rfloor$$$ which will help us in solving the problem

      • $$$\lfloor\frac{n}{i}\rfloor = \frac{n - (n \bmod i)}{i}$$$, from that we can deduce that $$$n \bmod i = n - i \cdot \lfloor\frac{n}{i}\rfloor$$$

      • There is some interesting fact about $$$\lfloor{\frac{n}{i}}\rfloor$$$, if we have $$$\lfloor{\frac{n}{i}}\rfloor = x$$$, we can say that $$$\frac{n}{i} - v = x$$$ where $$$0 \le v \lt 1$$$, we can deduce from this that $$$i = \frac{n}{x+v}$$$, then $$$\frac{n}{x+1} \lt i \le \frac{n}{x}$$$, so the possible integer values of $$$i$$$ which satisfy the equation $$$\lfloor{\frac{n}{i}}\rfloor$$$ lie in the interval $$$(\frac{n}{x+1},\frac{n}{x}]$$$, if you try to think about it, this is a more accurate interval for integer values : $$$(\lfloor\frac{n}{x+1}\rfloor,\lfloor\frac{n}{x}\rfloor]$$$

      • There is something else interesting about $$$\lfloor{\frac{n}{i}}\rfloor$$$, for each $$$i$$$ $$$(1\le i\le n)$$$, there is atmost $$$2\cdot\sqrt n$$$ different values for $$$\lfloor{\frac{n}{i}}\rfloor$$$, the reason for this is that there are $$$\sqrt n$$$ possible values for $$$i$$$ that satisfy $$$(1 \le i \le \sqrt n)$$$ and they yield at most $$$\sqrt n$$$ different values, and for the other $$$i$$$ $$$(\sqrt n \lt i \le n)$$$, $$$(1 \le \lfloor{\frac{n}{i}}\rfloor \le \sqrt n)$$$, yielding another $$$\sqrt n$$$ different values atmost, so there is atmost $$$2\cdot\sqrt n$$$ different values for the floor function

      If we created an array $$$A$$$ of size $$$n$$$ such that $$$A_i = \lfloor{\frac{n}{i}}\rfloor$$$, then array $$$A$$$ will consist of at most $$$2\cdot \sqrt n$$$ blocks of equal values, we can compress the array into an array of at most $$$2\cdot \sqrt n$$$ tuples $$$(l,r,x)$$$, where $$$l,r$$$ are the boundaries of the block, $$$x$$$ is the value of elements in the block

      So how to construct this compressed array? If we have the left boundary of a block $$$l$$$, then the value $$$x$$$ of the block will be $$$\lfloor{\frac{n}{l}}\rfloor$$$, and the value $$$r$$$ of a block is equal to the maximum value of $$$i$$$ which satisfies $$$\lfloor{\frac{n}{i}}\rfloor = x$$$, which is $$$\lfloor{\frac{n}{x}}\rfloor$$$

      Lets recap, if we have $$$l$$$, then $$$x = \lfloor{\frac{n}{l}}\rfloor$$$, $$$r = \lfloor{\frac{n}{x}}\rfloor$$$, the value of $$$l$$$ of the next block is equal to $$$r+1$$$ of the current block, since the value of $$$l$$$ of the first block is $$$1$$$, we can keep going with the following procedure : finding $$$x$$$,$$$r$$$ of the current block and $$$l$$$ of the next block, then go the next block until $$$l > n$$$ then we halt

      This compressed array is a very useful technique in a lot of problems involving the floor function, and we are going to use it in our problem

      Now enough talking about floor divisions, back to our problem, we want to calculate $$$f(n) = \sum\limits_{i=0}^{n}\sum\limits_{j=1}^{i}d(j)$$$, the answer to your problem is $$$f(N-1) + N$$$

      We can rewrite $$$f(n)$$$ as $$$f(n) = \sum\limits_{i=0}^{n}\sum\limits_{j=1}^{n}\lfloor{\frac{i}{j}}\rfloor$$$ based on the very first fact I stated above, and by reordering the sums we get $$$f(n) = \sum\limits_{m=1}^{n}\sum\limits_{i=0}^{n}\lfloor{\frac{i}{m}}\rfloor$$$

      Now for given values of $$$n,m$$$, we need to find a closed formula for $$$\sum\limits_{i=0}^{n}\lfloor\frac{i}{m}\rfloor = S(m)$$$, if we investigate $$$\lfloor\frac{i}{m}\rfloor$$$ starting from $$$i=0$$$, the first $$$m$$$ values are equal to $$$0$$$, the next $$$m$$$ values are equal to $$$1$$$, the next $$$m$$$ values are equal to $$$2$$$, $$$...$$$ etc

      So if we have the last value equal (call it $$$fl$$$) to $$$\lfloor\frac{n}{m}\rfloor$$$, then we are sure that all values from $$$0$$$ to $$$fl-1$$$ inclusive are repeated exactly $$$m$$$ times, so we are sure we already have $$$\sum\limits_{i=0}^{fl-1}i \cdot m = g(fl-1) \cdot m$$$ in our sum (where $$$g(n) = \sum\limits_{i=0}^{n}i = \frac{n \cdot (n+1)}{2}$$$), the remaining part are the values equal to $$$fl$$$, you can deduce that the count of these values is equal to $$$(n \bmod m) + 1$$$ (I will leave it as an exercise for you to proof why I am just tired don't kill me pls), $$$(n \bmod m) + 1$$$ can be rewritten as $$$n + 1 - m \cdot \lfloor\frac{n}{m}\rfloor$$$ = $$$n + 1 - fl \cdot m$$$

      So, we reached the conclusion that $$$S(m) = \sum\limits_{i=0}^{n}\lfloor\frac{i}{m}\rfloor = g(fl-1) \cdot m + fl \cdot (n + 1 - fl \cdot m)$$$ (here $$$fl = \lfloor\frac{n}{m}\rfloor$$$)

      So $$$f(n) = \sum\limits_{m=1}^{n}S(m)$$$, now we are going to use our secret weapon, the compressed array of size atmost $$$2 \cdot \sqrt n$$$

      We calculate the sum of answers over all blocks, for each $$$m$$$ between $$$l,r$$$ inclusive, the value of $$$\lfloor\frac{n}{m}\rfloor$$$ is equal to $$$x$$$

      So $$$S(m) = mg(x-1) + x(n + 1 - xm) = mg(x-1) + x(n+1) - x^{2}m = m(g(x-1)-x^2) + x(n+1)$$$

      So the summation over answers of the block $$$\sum\limits_{m=l}^{r} S(m) = \sum\limits_{m=l}^{r} m(g(x-1)-x^2) + x(n+1) = (g(r) - g(l-1))\cdot(g(x-1)-x^2) + x(n+1)\cdot(r+1-l)$$$, and thats the answer over one block, you just sum the answers of all blocks and you get your desired value of $$$f(n)$$$, since there are at most $$$2 \cdot \sqrt n$$$ blocks, then the final time complexity is $$$O(\sqrt n)$$$ per testcase

  • »
    »
    19 месяцев назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    I think complexity is, in fact, $$$O(n \log n)$$$.

    • »
      »
      »
      19 месяцев назад, # ^ |
      Rev. 3   Проголосовать: нравится +18 Проголосовать: не нравится

      Try running this code

      Code

      You will notice that $$$ans \lt 4\cdot 10^6$$$, and $$$\log \log 10^6 \gt 4$$$