SlideShare une entreprise Scribd logo
1  sur  11
Télécharger pour lire hors ligne
K-th String




原案:komiya, lyoz
解答:komiya, lyoz
 スライド:komiya
問題概要

●   長さNの文字列で、suffix arrayが与えられたもの
    と等しくなるようなもののうち、辞書順でK番目にく
    るものを求める問題。

●   N≦10^5
●   K≦10^18
●   アルファベットサイズ=:A≦26
観察:数え上げ

●   まず、与えられたSuffix Arrayが出てくるような文
    字列がいくつあるか数え上げてみよう。

●   inv[sa[i]] = iとする。
●   S[sa[i]] ≦ S[sa[i+1]]が必要。
●   上の式で、inv[sa[i]+1] > inv[sa[i+1]+1]なら等
    号をつけてはならない。
●   理由:文字列x, yについてx[1]=y[1]なら
     x≦y ⇔ x[2..]≦y[2..]
観察:数え上げ

●   具体的に、sa[] = {2,5,1,3,4}とする。
●   このとき、S[2]≦S[5]≦S[1]≦S[3]≦S[4]が必要。
●   S[2]=S[5]のとき、S[3..]<S[6..]=””である必要が
    あるが、これは成り立たない。なのでS[2]<S[5]。
●   S[5]=S[1]のとき、S[6..]<S[2..]である必要がある
    が、これは正しい。なのでS[5]≦S[1]。
●   同様にやって、S[2]<S[5]≦S[1]≦S[3]<S[4]。
●   これは必要十分。
観察:数え上げ

●   結局、以下のような場合の数に落ちる。
●   白い玉がN個と黒い玉A-1個を一列に並べる。
●   ただし、inv[sa[i]+1]>inv[sa[i+1]+1]ならi番目の
    白玉とi+1番目の白玉の間に少なくとも1個の黒
    い玉を置く必要がある。
●   このような白玉、黒玉の列と文字列が対応してる。
    S[sa[i]]=
     {'a' + (i番目の白玉の左側にある黒玉の個数)}
観察:数え上げ

●   「必ず黒玉をおかなきゃならない位置」を考えるの
    は面倒なので、そのような箇所がu個あるとき、そ
    のu個を最初から取り除いて考える。
●   つまり、白玉N個と黒玉A-1-u個を自由に並べて、
    その後黒玉u個を該当箇所に追加すると考える。
●   これだと、白玉N個と残りの黒玉A-1-u個を制約
    なく一列に並べる場合の数になり、
    combination(N+A-1-u, A-1-u)
    が答えとなる。
解法

●   「辞書順最小を求めよ」の典型パターンと同じよう
    に解く。
●   先頭から順に、「この文字に確定したら何通りの
    文字列が作れるか」を計算して1文字ずつ進めれ
    ばよい。
●   さっきと同じように、「黒玉をおかなきゃならない位
    置」は最後に考えるようにすると楽。
解法

●   i文字目を固定するとき、残りの文字の決め方が何
    通りあるかを効率的に計算したい。
●   A-1-u=10で、4文字目までは確定している場合。
      i        0   1   2   3   4   5   6  7 8
      sa[i]    -   4   2   5   6   1   3  7 -
      黒玉の累積値   0   2   2   未   未   7   10 未 10

●   上の場合は、区間[(2,5),(6,8)]を持っておく。それ
    ぞれの区間は互いに干渉しない。
解答

●   「両端の累積値が固定された区間」同士は互いに
    独立に考えてよい。
●   各区間ごとに、「白玉と黒玉を一列に並べる場合
    の数」を計算しておいて、その区間の列を持ってお
    く。
●   i文字目を固定したときの場合の数は、新たに区
    間のひとつを分割してそれぞれの場合の数の積
    が何通りになるか計算すればよい。
高速化

●   これを愚直にやると、区間の数がO(N)個になりう
    るので全体でO(N^2)となりうまくいかない。
●   しかし、自由度のある区間は高々A個しかない。
●   なので、自由度の存在しない区間については保持
    しないようにする。
●   こうすることで、O(N*A)となり間に合うようになる。
注意点

●   全体として、積をとる場面でオーバーフローがおき
    うるので、以下のような関数を用意しておくと楽。
     long mul(long x, long y) {
          return (double)x*y>INF?INF:x*y;
      }
●   二項係数の計算は、パスカルの三角形を使えば
    前処理で必要な分を全部計算しておける。

Contenu connexe

Tendances

AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説AtCoder Inc.
 
Permutation
PermutationPermutation
Permutationoupc
 
VBAで数値計算 04 ニュートン法
VBAで数値計算 04 ニュートン法VBAで数値計算 04 ニュートン法
VBAで数値計算 04 ニュートン法Katsuhiro Morishita
 
RUPC2014_Day2_I
RUPC2014_Day2_IRUPC2014_Day2_I
RUPC2014_Day2_Is1190048
 
AtCoder Beginner Contest 014 解説
AtCoder Beginner Contest 014 解説AtCoder Beginner Contest 014 解説
AtCoder Beginner Contest 014 解説AtCoder Inc.
 
AtCoder Regular Contest 046
AtCoder Regular Contest 046AtCoder Regular Contest 046
AtCoder Regular Contest 046AtCoder Inc.
 
AtCoder Regular Contest 019 解説
AtCoder Regular Contest 019 解説AtCoder Regular Contest 019 解説
AtCoder Regular Contest 019 解説AtCoder Inc.
 
AtCoder Regular Contest 027 解説
AtCoder Regular Contest 027 解説AtCoder Regular Contest 027 解説
AtCoder Regular Contest 027 解説AtCoder Inc.
 
AtCoder Regular Contest 024 解説
AtCoder Regular Contest 024 解説AtCoder Regular Contest 024 解説
AtCoder Regular Contest 024 解説AtCoder Inc.
 
SuperCon2010予選アルゴリズム解説
SuperCon2010予選アルゴリズム解説SuperCon2010予選アルゴリズム解説
SuperCon2010予選アルゴリズム解説natrium11321
 
【第34回数学カフェの予習会#1】微分と代数学のつながり
【第34回数学カフェの予習会#1】微分と代数学のつながり【第34回数学カフェの予習会#1】微分と代数学のつながり
【第34回数学カフェの予習会#1】微分と代数学のつながりMathCafe
 
Atcoder Regular Contest 014 解説
Atcoder Regular Contest 014 解説Atcoder Regular Contest 014 解説
Atcoder Regular Contest 014 解説光喜 濱屋
 
Anagram
AnagramAnagram
Anagramoupc
 
At coder regular contest 013 解説
At coder regular contest 013 解説At coder regular contest 013 解説
At coder regular contest 013 解説光喜 濱屋
 
RUPC2014_Day2_J
RUPC2014_Day2_JRUPC2014_Day2_J
RUPC2014_Day2_Js1190048
 

Tendances (20)

Arc041
Arc041Arc041
Arc041
 
arc047
arc047arc047
arc047
 
AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説
 
abc027
abc027abc027
abc027
 
Permutation
PermutationPermutation
Permutation
 
VBAで数値計算 04 ニュートン法
VBAで数値計算 04 ニュートン法VBAで数値計算 04 ニュートン法
VBAで数値計算 04 ニュートン法
 
RUPC2014_Day2_I
RUPC2014_Day2_IRUPC2014_Day2_I
RUPC2014_Day2_I
 
AtCoder Beginner Contest 014 解説
AtCoder Beginner Contest 014 解説AtCoder Beginner Contest 014 解説
AtCoder Beginner Contest 014 解説
 
AtCoder Regular Contest 046
AtCoder Regular Contest 046AtCoder Regular Contest 046
AtCoder Regular Contest 046
 
AtCoder Regular Contest 019 解説
AtCoder Regular Contest 019 解説AtCoder Regular Contest 019 解説
AtCoder Regular Contest 019 解説
 
AtCoder Regular Contest 027 解説
AtCoder Regular Contest 027 解説AtCoder Regular Contest 027 解説
AtCoder Regular Contest 027 解説
 
Divisor
DivisorDivisor
Divisor
 
AtCoder Regular Contest 024 解説
AtCoder Regular Contest 024 解説AtCoder Regular Contest 024 解説
AtCoder Regular Contest 024 解説
 
SuperCon2010予選アルゴリズム解説
SuperCon2010予選アルゴリズム解説SuperCon2010予選アルゴリズム解説
SuperCon2010予選アルゴリズム解説
 
【第34回数学カフェの予習会#1】微分と代数学のつながり
【第34回数学カフェの予習会#1】微分と代数学のつながり【第34回数学カフェの予習会#1】微分と代数学のつながり
【第34回数学カフェの予習会#1】微分と代数学のつながり
 
Atcoder Regular Contest 014 解説
Atcoder Regular Contest 014 解説Atcoder Regular Contest 014 解説
Atcoder Regular Contest 014 解説
 
Anagram
AnagramAnagram
Anagram
 
IJPC C解説
IJPC C解説IJPC C解説
IJPC C解説
 
At coder regular contest 013 解説
At coder regular contest 013 解説At coder regular contest 013 解説
At coder regular contest 013 解説
 
RUPC2014_Day2_J
RUPC2014_Day2_JRUPC2014_Day2_J
RUPC2014_Day2_J
 

En vedette

Comment
CommentComment
Commentoupc
 
Cube
CubeCube
Cubeoupc
 
One
OneOne
Oneoupc
 
Magical
MagicalMagical
Magicaloupc
 
Replace
ReplaceReplace
Replaceoupc
 
Goto
GotoGoto
Gotooupc
 
Palin
PalinPalin
Palinoupc
 
Paren
ParenParen
Parenoupc
 
Gcd
GcdGcd
Gcdoupc
 
Sort
SortSort
Sortoupc
 
Rmq
RmqRmq
Rmqoupc
 
Sharp2sat
Sharp2satSharp2sat
Sharp2satoupc
 
Trip
TripTrip
Tripoupc
 
Segpair
SegpairSegpair
Segpairoupc
 
Sanpo
SanpoSanpo
Sanpooupc
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門Yoichi Iwata
 

En vedette (17)

Comment
CommentComment
Comment
 
Cube
CubeCube
Cube
 
One
OneOne
One
 
1
11
1
 
Magical
MagicalMagical
Magical
 
Replace
ReplaceReplace
Replace
 
Goto
GotoGoto
Goto
 
Palin
PalinPalin
Palin
 
Paren
ParenParen
Paren
 
Gcd
GcdGcd
Gcd
 
Sort
SortSort
Sort
 
Rmq
RmqRmq
Rmq
 
Sharp2sat
Sharp2satSharp2sat
Sharp2sat
 
Trip
TripTrip
Trip
 
Segpair
SegpairSegpair
Segpair
 
Sanpo
SanpoSanpo
Sanpo
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
 

Similaire à Kth (6)

CODE FESTIVAL 2014 エキシビジョン 解説
CODE FESTIVAL 2014 エキシビジョン 解説CODE FESTIVAL 2014 エキシビジョン 解説
CODE FESTIVAL 2014 エキシビジョン 解説
 
『上級演習』確率
『上級演習』確率『上級演習』確率
『上級演習』確率
 
K2PC Div1 E 暗号化
K2PC Div1 E 暗号化K2PC Div1 E 暗号化
K2PC Div1 E 暗号化
 
Aizu-2017: B
Aizu-2017: BAizu-2017: B
Aizu-2017: B
 
Square869120 contest #2
Square869120 contest #2Square869120 contest #2
Square869120 contest #2
 
写像 12 相
写像 12 相写像 12 相
写像 12 相
 

Plus de oupc

Knapsack
KnapsackKnapsack
Knapsackoupc
 
Game
GameGame
Gameoupc
 
Four op
Four opFour op
Four opoupc
 
Divisor
DivisorDivisor
Divisoroupc
 
Division
DivisionDivision
Divisionoupc
 
Comment
CommentComment
Commentoupc
 

Plus de oupc (7)

Knapsack
KnapsackKnapsack
Knapsack
 
Game
GameGame
Game
 
Four op
Four opFour op
Four op
 
Divisor
DivisorDivisor
Divisor
 
Division
DivisionDivision
Division
 
A
AA
A
 
Comment
CommentComment
Comment
 

Kth

  • 2. 問題概要 ● 長さNの文字列で、suffix arrayが与えられたもの と等しくなるようなもののうち、辞書順でK番目にく るものを求める問題。 ● N≦10^5 ● K≦10^18 ● アルファベットサイズ=:A≦26
  • 3. 観察:数え上げ ● まず、与えられたSuffix Arrayが出てくるような文 字列がいくつあるか数え上げてみよう。 ● inv[sa[i]] = iとする。 ● S[sa[i]] ≦ S[sa[i+1]]が必要。 ● 上の式で、inv[sa[i]+1] > inv[sa[i+1]+1]なら等 号をつけてはならない。 ● 理由:文字列x, yについてx[1]=y[1]なら  x≦y ⇔ x[2..]≦y[2..]
  • 4. 観察:数え上げ ● 具体的に、sa[] = {2,5,1,3,4}とする。 ● このとき、S[2]≦S[5]≦S[1]≦S[3]≦S[4]が必要。 ● S[2]=S[5]のとき、S[3..]<S[6..]=””である必要が あるが、これは成り立たない。なのでS[2]<S[5]。 ● S[5]=S[1]のとき、S[6..]<S[2..]である必要がある が、これは正しい。なのでS[5]≦S[1]。 ● 同様にやって、S[2]<S[5]≦S[1]≦S[3]<S[4]。 ● これは必要十分。
  • 5. 観察:数え上げ ● 結局、以下のような場合の数に落ちる。 ● 白い玉がN個と黒い玉A-1個を一列に並べる。 ● ただし、inv[sa[i]+1]>inv[sa[i+1]+1]ならi番目の 白玉とi+1番目の白玉の間に少なくとも1個の黒 い玉を置く必要がある。 ● このような白玉、黒玉の列と文字列が対応してる。 S[sa[i]]= {'a' + (i番目の白玉の左側にある黒玉の個数)}
  • 6. 観察:数え上げ ● 「必ず黒玉をおかなきゃならない位置」を考えるの は面倒なので、そのような箇所がu個あるとき、そ のu個を最初から取り除いて考える。 ● つまり、白玉N個と黒玉A-1-u個を自由に並べて、 その後黒玉u個を該当箇所に追加すると考える。 ● これだと、白玉N個と残りの黒玉A-1-u個を制約 なく一列に並べる場合の数になり、 combination(N+A-1-u, A-1-u) が答えとなる。
  • 7. 解法 ● 「辞書順最小を求めよ」の典型パターンと同じよう に解く。 ● 先頭から順に、「この文字に確定したら何通りの 文字列が作れるか」を計算して1文字ずつ進めれ ばよい。 ● さっきと同じように、「黒玉をおかなきゃならない位 置」は最後に考えるようにすると楽。
  • 8. 解法 ● i文字目を固定するとき、残りの文字の決め方が何 通りあるかを効率的に計算したい。 ● A-1-u=10で、4文字目までは確定している場合。 i 0 1 2 3 4 5 6 7 8 sa[i] - 4 2 5 6 1 3 7 - 黒玉の累積値 0 2 2 未 未 7 10 未 10 ● 上の場合は、区間[(2,5),(6,8)]を持っておく。それ ぞれの区間は互いに干渉しない。
  • 9. 解答 ● 「両端の累積値が固定された区間」同士は互いに 独立に考えてよい。 ● 各区間ごとに、「白玉と黒玉を一列に並べる場合 の数」を計算しておいて、その区間の列を持ってお く。 ● i文字目を固定したときの場合の数は、新たに区 間のひとつを分割してそれぞれの場合の数の積 が何通りになるか計算すればよい。
  • 10. 高速化 ● これを愚直にやると、区間の数がO(N)個になりう るので全体でO(N^2)となりうまくいかない。 ● しかし、自由度のある区間は高々A個しかない。 ● なので、自由度の存在しない区間については保持 しないようにする。 ● こうすることで、O(N*A)となり間に合うようになる。
  • 11. 注意点 ● 全体として、積をとる場面でオーバーフローがおき うるので、以下のような関数を用意しておくと楽。  long mul(long x, long y) { return (double)x*y>INF?INF:x*y; } ● 二項係数の計算は、パスカルの三角形を使えば 前処理で必要な分を全部計算しておける。