Enchom's blog

By Enchom, history, 9 years ago, In English

Hello everybody,

Today was the second day of RMI(Romanian master of informatics) and I participated onsite. It took me a couple of hours to solve two of the problems and then I had whole three to tackle the last one. Alas, it turned out to be too difficult for me to get more than 10-20 points.

The short statement of the problem is simply :

Support 2 types of queries on an array of size N:

1) Given "L R" find greatest common divisor of all numbers from index L to R, that is gcd(a[L], a[L+1],..., a[R])

2) Given "L R k" update the array in the following way:

a[L]+=k

a[L+1]+=2*k

...

a[R]+=(R-L+1)*k

There are up to 100,000 numbers and queries with time limit of 1s and memory limit of 128MB. The initial numbers are up to 200,000,000 and in each query of type 2 we can have k up to 200,000,000 (resulting in numbers becoming as big as 10^18).

Query problems are usually my favourite but I couldn't come up with anything here. The queries just seem very different. If someone has some solution, please share.

  • Vote: I like it
  • +18
  • Vote: I do not like it

»
9 years ago, # |
Rev. 5   Vote: I like it +34 Vote: I do not like it

Key observation in this problem is that

Unable to parse markup [type=CF_TEX]

. It is quite easy to understand : if all xi are divisible by d, then all

Unable to parse markup [type=CF_TEX]

are divisible by d, if

Unable to parse markup [type=CF_TEX]

are divisible by d, then their prefix sum

Unable to parse markup [type=CF_TEX]

is divisible by d.

First, you can keep ai in segment tree with operations "add arithmetic progression on segment" and "request i-th element". For simplicity, I'll assume

Unable to parse markup [type=CF_TEX]

later, other cases are solved easily when we have such segment tree.

Second,

Unable to parse markup [type=CF_TEX]

.

Let's say

Unable to parse markup [type=CF_TEX]

. Let's forget about existence of a for a moment and reformulate statement in new variables: in first operation we need to calculate gcd on segment, thanks to above equality, in second operation we need to add k to some segment of b, and add

Unable to parse markup [type=CF_TEX]

to some other position of b. So we can use segment tree on bi in similar fashion to find

Unable to parse markup [type=CF_TEX]

. But

Unable to parse markup [type=CF_TEX]

. So if

Unable to parse markup [type=CF_TEX]

, then we need to calculate

Unable to parse markup [type=CF_TEX]

. But when we add some value to segment of b not more than two values of c change, so we can use usual segment tree for "change single value" and "calculate gcd on segment" for c.

The answer is

Unable to parse markup [type=CF_TEX]

, which can be calculated using described segment trees easily.
  • »
    »
    9 years ago, # ^ |
      Vote: I like it +3 Vote: I do not like it

    I got it, thanks a lot!

    During the competition I thought about differences but found that

    Unable to parse markup [type=CF_TEX]

    is not always the gcd of differences, so I dropped the idea. Didn't realise you have to add al to the differences to get the correct gcd.