活跃农民
- 积分
- 446
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2018-3-21
- 最后登录
- 1970-1-1
|
本帖最后由 jgao93 于 2021-2-14 11:40 编辑
如果只是要求sample的复杂度为O(logn)的话用线段树是可以(不好意思这里的n是楼主的k)
- class SamplingSegmentTree {
- public:
- SamplingSegmentTree(const vector<int>& weights) {
- num_elements_ = weights.size();
- weight_nodes_.resize(4 * num_elements_);
- Construct(weights, 0, num_elements_ - 1, 0);
- }
-
- int Sample() {
- int target_weight = rand() % weight_nodes_[0];
- int selected = -1;
- Sample(0, num_elements_ - 1, 0, target_weight, selected);
- return selected;
- }
-
- private:
- size_t num_elements_;
- vector<int> weight_nodes_;
-
- void Construct(const vector<int>& weights, int wl, int wr, int t) {
- if (wl > wr) return;
- if (wl == wr) {
- weight_nodes_[t] = weights[wl];
- } else {
- int tl = 2 * t + 1;
- int tr = 2 * t + 2;
- int wm = wl + (wr - wl) / 2;
- Construct(weights, wl, wm, tl);
- Construct(weights, wm + 1, wr, tr);
- weight_nodes_[t] = weight_nodes_[tl] + weight_nodes_[tr];
- }
- }
-
- void Sample(int wl, int wr, int t, int& target_weight, int& selected) {
- if (selected != -1) return;
- if (wl > wr) return;
- if (wl == wr) {
- target_weight -= weight_nodes_[t];
- if (target_weight < 0) {
- selected = wl;
- weight_nodes_[t] = 0;
- }
- } else {
- int tl = 2 * t + 1;
- int tr = 2 * t + 2;
- int wm = wl + (wr - wl) / 2;
- Sample(wl, wm, tl, target_weight, selected);
- Sample(wm + 1, wr, tr, target_weight, selected);
- weight_nodes_[t] = weight_nodes_[tl] + weight_nodes_[tr];
- }
- }
- };
- int main() {
- map<string, int> distribution;
- for (int i = 0; i < 100000; ++i) {
- SamplingSegmentTree sst({1,1,1,1,1});
- vector<int> sample;
- for (int j = 0; j < 3; ++j) {
- sample.push_back(sst.Sample());
- }
- sort(sample.begin(), sample.end());
- string key;
- for (int s: sample) key += to_string(s) + " ";
- ++distribution[key];
- }
- for (auto& entry : distribution) {
- cout << entry.first << ": " << entry.second << endl;
- }
- }
复制代码
输出结果:
- 0 1 2 : 10063
- 0 1 3 : 10054
- 0 1 4 : 10092
- 0 2 3 : 9803
- 0 2 4 : 10025
- 0 3 4 : 10018
- 1 2 3 : 9945
- 1 2 4 : 9944
- 1 3 4 : 9964
- 2 3 4 : 10092
复制代码
|
|