2

IDEONE: http://ideone.com/uSqSq7

#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;

struct node
{
    int value, position;
    bool left, right;
    bool operator < (const node& a) const
    {
        return value < a.value;
    }
};

int main()
{
    int n;
    cin >> n;

    vector < node > a(n);
    set < node > s;

    for (auto &i: a)
    {
        cin >> i.value;
        i.left=i.right=0;
    }

    a[0].position=1;
    s.insert(a[0]);

    for (int i=1; i<n; i++)
    {
        auto it=s.upper_bound(a[i]);
        auto it2=it; --it2;
        if (it==s.begin())
        {
            a[i].position=2*it->position;
            s.insert(a[i]);
            it->left=1;
        }
        else if (it==s.end())
        {
            a[i].position=2*(--it)->position+1;
            s.insert(a[i]);
            it->right=1;
        }
        else
        {
            if (it2->right==0)
            {
                a[i].position=2*it2->position+1;
                s.insert(a[i]);
                it2->right=1;
            }
            else
            {
                a[i].position=2*it->position;
                s.insert(a[i]);
                it->left=1;
            }
        }
    }

    for (auto i: a) cout << i.position << ' ';
}

When I compile this code, I get

error: assignment of member ‘node::right’ in read-only object

I think this has something to do with the const in bool operator <, but I cannot get rid of it as it is necessary to create the set.

hanshenrik
  • 19,904
  • 4
  • 43
  • 89
anukul
  • 1,922
  • 1
  • 19
  • 37

2 Answers2

5

Angelika Langer once wrote a piece about this: Are Set Iterators Mutable or Immutable?.

You can solve this by defining the Node members immaterial for the set ordering as mutable:

mutable bool left, right;

(see a building version in ideone.)

Personally, I would consider a design mapping the immutable part to mutable parts using a map.

anukul
  • 1,922
  • 1
  • 19
  • 37
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
0

Problem:

Remember that keys in a std::set are constant. You can't change a key after it's inserted into the set. So when you dereference the iterator, it necessarily returns a constant reference.

const node& n = (*it);
n->left = 1; //It will not allow you to change as n is const &.

Solution:

As Ami Tavory answered, you can declare left and right as mutable.

CreativeMind
  • 897
  • 6
  • 19