首先放代码:
for(int s1=s,s2;s1;s1=(s1-1)&s) s2=s^s1;
其中$s$表示集合,$s_1$表示子集,$s_2$表示补集。
首先一个集合本身就是自己的子集,所以我们给$s_1$赋初值为$s$。
然后有一个关于按位与的性质:若$a<b$,则$aominus bsubseteq b$,其中$ominus$表示按位与。
于是我们可以将$s_1$减一,再和$s$做按位与,就可以得到$s_1$的次小子集。
再详细一点,$s_1$减一,就是把$lowbit(s_1)$位变为$0$,更小的几位变为$1$,然后和$s$做按位与,就是把多余的$1$抹掉。这样得到的就是次小子集。