数列(Ai)が整数xをcx個含むとする。また、整数xが代表になるような部分列でちょうどk個のxを含むものの総数をf(x,k)とする。f(x,k)を二項係数で表すと、以下のようになる:
f(x,k):=(i=0∑k−1(ic1)...i=0∑k−1(icx−1))(kcx)(i=0∑k(icx+1)...i=0∑k(icN))
f(x,k)をN通りの引数について足せばよいが、毎回すべての二項係数を掛け算していては間に合わない。そこで、dp[x]:=∑i(icx)という形の列をセグメント木で持っておくことを考える。dpのそれぞれの値が適切なkに対応していれば、f(x,k)はdp[1...x−1]の積と (kcx)とdp[x+1...N]の積を掛けて求まることになる。k=0からfを求めていくとして、dpの末尾からkが増えていくので、kの昇順、タイブレークはxの降順にf(x,k)を求めつつdpを更新していくと、一回の更新がO(logN)でできる。