1 of 52

Square root decomposition

Nils Gustafsson

2 of 52

Vad är Sqrt-decomposition?

3 of 52

Vad är Sqrt-decomposition?

4 of 52

Vad är Sqrt-decomposition?

5 of 52

Vad är Sqrt-decomposition?

6 of 52

Intervallsummor

Givet är N tal och Q queries på formen

  1. Ändra tal nummer i till X.
  2. Skriv ut summan av talen i intervallet L <= i <= R.

7 of 52

Intervallsummor

Givet är N tal och Q queries på formen

  1. Ändra tal nummer i till X.
  2. Skriv ut summan av talen i intervallet L <= i <= R.

Lösning:

Naiv lösning: O(NQ)

8 of 52

Intervallsummor

Givet är N tal och Q queries på formen

  1. Ändra tal nummer i till X.
  2. Skriv ut summan av talen i intervallet L <= i <= R.

Lösning:

Naiv lösning: O(NQ)

Segmentträd/Fenwickträd: O(Qlog(N))

9 of 52

Intervallsummor

Givet är N tal och Q queries på formen

  1. Ändra tal nummer i till X.
  2. Skriv ut summan av talen i intervallet L <= i <= R.

Lösning:

Naiv lösning: O(NQ)

Segmentträd/Fenwickträd: O(Qlog(N))

SQRT-decomposition: O(Qsqrt(N))

10 of 52

Intervallsummor

Dela in intervallet i block av storlek B.

Håll koll på summan av alla tal i varje block.

11 of 52

Intervallsummor

Dela in intervallet i block av storlek B.

Håll koll på summan av alla tal i varje block.

12 of 52

Intervallsummor

Dela in intervallet i block av storlek B.

Håll koll på summan av alla tal i varje block.

Antal operationer: 2B + N/B

13 of 52

Intervallsummor

Hur sköter vi uppdateringarna?

14 of 52

Intervallsummor

Hur sköter vi uppdateringarna?

Räkna om all information i uppdateringens block:

15 of 52

Intervallsummor

Specialfall: intervallet är helt inuti ett block.

16 of 52

Intervallsummor

Givet är N tal och Q queries på formen

  1. Ändra alla [L <= i <= R] till X.
  2. Öka alla [L <= i <= R] med X.
  3. Skriv ut summan av talen i intervallet [L <= i <= R].

17 of 52

Intervallsummor

Givet är N tal och Q queries på formen

  1. Ändra alla [L <= i <= R] till X.
  2. Öka alla [L <= i <= R] med X.
  3. Skriv ut summan av talen i intervallet [L <= i <= R].

sum

lazy_set

lazy_sum

18 of 52

Mo’s algoritm

19 of 52

Mo’s algoritm

https://codeforces.com/problemset/problem/86/D

Givet är N tal och Q intervall.

För varje intervall:

Låt Kx vara antalet gånger talet x förekommer i intervallet. Räkna ut summan av Kx2 x.

20 of 52

Mo’s algoritm

https://codeforces.com/problemset/problem/86/D

Givet är N tal och Q intervall.

För varje intervall:

Låt Kx vara antalet gånger talet x förekommer i intervallet. Räkna ut summan av Kx2 x.

3 2 4 4 2 3 1 2 5 2 3 1 1 2 4 5 2 3

3*3*1 + 2*2*2 + 2*2*3 + 1*1*5 = 34

21 of 52

Mo’s algoritm

Vi behöver veta hur många gånger varje tal förekommer, men det är svårt att kombinera ihop den informationen mellan intervall.

3 2 4 4 2 3 1 2 5 2 3 1 1 2 4 5 2 3

F = [0, 3, 2, 2, 0, 1], ans = 34

22 of 52

Mo’s algoritm

Vi behöver veta hur många gånger varje tal förekommer, men det är svårt att kombinera ihop den informationen mellan intervall.

Däremot kan vi lätt expandera/krympa ett intervall i O(1).

3 2 4 4 2 3 1 2 5 2 3 1 1 2 4 5 2 3

F = [0, 3, 2, 2, 0, 1], ans = 34

23 of 52

Mo’s algoritm

Vi behöver veta hur många gånger varje tal förekommer, men det är svårt att kombinera ihop den informationen mellan intervall.

Däremot kan vi lätt expandera/krympa ett intervall i O(1).

3 2 4 4 2 3 1 2 5 2 3 1 1 2 4 5 2 3

F = [0, 3, 3, 2, 0, 1], ans = 44

F[2] += 1

24 of 52

Mo’s algoritm

Vi behöver veta hur många gånger varje tal förekommer, men det är svårt att kombinera ihop den informationen mellan intervall.

Däremot kan vi lätt expandera/krympa ett intervall i O(1).

3 2 4 4 2 3 1 2 5 2 3 1 1 2 4 5 2 3

F = [0, 3, 3, 1, 0, 1], ans = 35

F[3] -= 1

25 of 52

Mo’s algoritm

Lösning: Håll koll på ändpunkterna och “vandra” förbi alla intervall. Att vandra från [L1, R1] till [L2, R2] tar |L1-L2| + |R1-R2| steg.

3 2 4 4 2 3 1 2 5 2 3 1 1 2 4 5 2 3

26 of 52

Mo’s algoritm

Lösning: Håll koll på ändpunkterna och “vandra” förbi alla intervall. Att vandra från [L1, R1] till [L2, R2] tar |L1-L2| + |R1-R2| steg.

Det tar fortfarande O(NQ) i värsta fall. Kan vi besöka intervallen i en ordning som gör att går snabbare?

3 2 4 4 2 3 1 2 5 2 3 1 1 2 4 5 2 3

27 of 52

Mo’s algoritm

Dela in intervallet i block av storlek B. Sortera intervallen med avseende på:

  1. Vilket block deras vänsterändpunkt tillhör.
  2. Deras högerändpunkt.

28 of 52

Mo’s algoritm

Dela in intervallet i block av storlek B. Sortera intervallen med avseende på:

  • Vilket block deras vänsterändpunkt tillhör.
  • Deras högerändpunkt.

29 of 52

Mo’s algoritm

Dela in intervallet i block av storlek B. Sortera intervallen med avseende på:

  • Vilket block deras vänsterändpunkt tillhör.
  • Deras högerändpunkt.

30 of 52

Mo’s algoritm

Dela in intervallet i block av storlek B. Sortera intervallen med avseende på:

  • Vilket block deras vänsterändpunkt tillhör.
  • Deras högerändpunkt.

31 of 52

Mo’s algoritm

Dela in intervallet i block av storlek B. Sortera intervallen med avseende på:

  • Vilket block deras vänsterändpunkt tillhör.
  • Deras högerändpunkt.

32 of 52

Mo’s algoritm

Dela in intervallet i block av storlek B. Sortera intervallen med avseende på:

  • Vilket block deras vänsterändpunkt tillhör.
  • Deras högerändpunkt.

Vänsterändpunkterna färdas högst B mellan par av intervall, totalt QB.

Högerändpunkterna färdas N för varje block, totalt N2/B.

33 of 52

Mo’s algoritm

Dela in intervallet i block av storlek B. Sortera intervallen med avseende på:

  • Vilket block deras vänsterändpunkt tillhör.
  • Deras högerändpunkt.

Vänsterändpunkterna färdas högst B mellan par av intervall, totalt QB.

Högerändpunkterna färdas N för varje block, totalt N2/B.

34 of 52

Mo’s algoritm

Antal steg mellan två intervall |L1-L2| + |R1-R2| är manhattanavståndet mellan punkterna (L1, R1) och (L2, R2):

35 of 52

Mo’s algoritm

Antal steg mellan två intervall |L1-L2| + |R1-R2| är manhattanavståndet mellan punkterna (L1, R1) och (L2, R2):

36 of 52

Räkna trianglar

37 of 52

Räkna trianglar

Givet en graf med N noder och M kanter, räkna hur många trianglar det finns i grafen.

N,M <= 105.

38 of 52

Räkna trianglar

Givet en graf med N noder och M kanter, räkna hur många trianglar det finns i grafen.

N,M <= 105.

Först, lagra alla kanter i en hashtabell (unordered_set) så att vi snabbt kan kolla upp om ett par av noder har en kant.

Loopa sedan igenom alla par av grannar för varje nod.

Varje triangel räknas då 3 gånger.

39 of 52

Räkna trianglar

Givet en graf med N noder och M kanter, räkna hur många trianglar det finns i grafen.

N,M <= 105.

Först, lagra alla kanter i en hashtabell (unordered_set) så att vi snabbt kan kolla upp om ett par av noder har en kant.

Loopa sedan igenom alla par av grannar för varje nod.

Varje triangel räknas då 3 gånger.

40 of 52

Räkna trianglar

Problemet är noder med väldigt många grannar. Men det finns inte så många såna noder...

41 of 52

Räkna trianglar

Problemet är noder med väldigt många grannar. Men det finns inte så många såna noder…

Ta bara noder med och kör den förra lösningen. Antalet iterationer

är som störst när noder har grad dvs.

42 of 52

Räkna trianglar

Problemet är noder med väldigt många grannar. Men det finns inte så många såna noder…

Ta bara noder med och kör den förra lösningen. Antalet iterationer

är som störst när noder har grad dvs.

3

2

1

0

43 of 52

Räkna trianglar

På det här sättet kan vi räkna alla trianglar med minst en “lätt” nod som hörn, men vi missar alla trianglar med tre “tunga” noder…

Men det finns bara noder med fler än grannar!

Vi kan kolla alla tripplar med såna noder:

0

44 of 52

Dynamic connectivity

45 of 52

Dynamic connectivity

Givet är en graf med N noder och M kanter, och Q queries på formen:

  1. Lägg till en kant.
  2. Ta bort en kant.
  3. Hitta om två noder u och v är i samma komponent.

46 of 52

Dynamic connectivity

Dela in alla queries i block av storlek .

47 of 52

Dynamic connectivity

Dela in alla queries i block av storlek .

I början av varje block, bygg ihop hela grafen i linjär tid.

48 of 52

Dynamic connectivity

Dela in alla queries i block av storlek .

I början av varje block, bygg ihop hela grafen i linjär tid.

För varje block, tjuvkika på alla queries i det blocket. Markera alla noder som deltar i någon av dessa. Det finns bara såna noder.

49 of 52

Dynamic connectivity

50 of 52

Dynamic connectivity

Komprimerad graf med storlek

51 of 52

Dynamic connectivity

Dela in alla queries i block av storlek .

I början av varje block, kolla på alla queries i det blocket och bygg ihop den komprimerade grafen.

För varje query, sök i den komprimerade grafen med DFS.

52 of 52

Problem