Indiot's blog

By Indiot, history, 3 months ago, In English

Hi~

To be able to get the hell out of this grey color, i'm learning new data structures. One of those is Fenwick Tree. By copying code of others on the internet, i'm now able to perform some basic operations such as min / max/ sum on a specific interval. Now here come a new problem, how to find the maximum X * f(X) on range [0, r], f(X) here denotes the occurrences of X within that interval. Thank you all, I much appreciate it!

  • Vote: I like it
  • -8
  • Vote: I do not like it

»
3 months ago, # |
  Vote: I like it 0 Vote: I do not like it

If I understood the problem correctly, you can solve the problem offline.

Since all queries have the same startpoint 0, sort them by their endpoint in ascending order.

Now you can you can compress all values in the array you are performing the queries and build a fenwick tree with size N where N is the number of distinct compressed values.

To process the queries maintain a pointer that only moves to the right. In the first query you move it from 0 to r1, in the second query from r1 to r2 and so on.

When you move the pointer to new index, you consider the value at that index, let it be X, then you add X on its position in the fenwick tree. To answer the query you just need to query the maximum value in the tree

  • »
    »
    3 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Hey, thanks for your detailed response! Actually the original problem requires update operation (add / remove element). So here is my code:

    code

    But it does not give the right answer, where am I missing here? tks again

    • »
      »
      »
      3 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      You didn't specify that the problem has updates, so I thought you only have to answer queires. Sorry.

      • »
        »
        »
        »
        3 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it
        full code

        Original problem (japanese)

      • »
        »
        »
        »
        3 months ago, # ^ |
        Rev. 2   Vote: I like it 0 Vote: I do not like it

        that's my fault to be honest

        edit: never mind, i solved the problem

        • »
          »
          »
          »
          »
          3 months ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          How did you solved the problem?

          • »
            »
            »
            »
            »
            »
            3 months ago, # ^ |
              Vote: I like it +3 Vote: I do not like it
            AC code

            Normal segment tree would not pass the time limit so I used efficient segment tree

»
3 months ago, # |
Rev. 2   Vote: I like it +3 Vote: I do not like it

Fun fact: Fenwick tree does not support non-invertible operations, that is, it's impossible to calculate $$$v[l] \circ v[l + 1] \circ \ldots \circ v[r]$$$ for an arbitrary $$$l, r$$$ if $$$\circ$$$ is $$$max/min/gcd$$$ etc. (however, we can support something like: 1) calculate minimum value among $$$v[l..r]$$$ 2) decrease $$$v[i]$$$ by $$$x$$$)

So, in general, your problem is not solvable with single Fenwick tree (but the comment above describes a decent solution).
P.S. I understand, that it is not part of your quiestion, but.. learning advanced (and not so advanced) data structures, you only become able to overkill some problems, while not improving your problem solving skills. The better option is to take a break (because when you're lost in desperation, your motivation level is really low) and get back to grinding as soon as you feel missed.
P.P.S. And yes, the previous paragraph is not like "stop learning useless algorithms, learn how to use binary search" — that's a problem i've been suffering from for a long time (like $$$80$$$% of time since i've started doing CP)

  • »
    »
    3 months ago, # ^ |
      Vote: I like it +3 Vote: I do not like it

    that's an honest advice that every newbie needs, thank you!

    • »
      »
      »
      3 months ago, # ^ |
      Rev. 2   Vote: I like it 0 Vote: I do not like it

      If you need non-reversible operations just use segment tree which is probably even simpler to implement and understand with comparable performance.

»
3 months ago, # |
Rev. 3   Vote: I like it +16 Vote: I do not like it

You don't need Fenwick tree here, just map. Given a fixed array we precompute all queries. Just walk the array from left to right maintaining a map<int,int> f; that counts occurrences of each value. Also, keep the maximum x*f[x] seen so far. That value is the answer to the current prefix, so we can store that in an array.

int n; cin >> n;
vector<int> a(n); forn(i,n) cin >> a[i];

map<int, int> f;
vector<long long> b(n);
long long ans = 0;
forn(i,n) {
  int x = a[i];
  f[x]++;
  ans = max(ans, 1ll*x*f[x]);
  b[i] = ans;
}

In the end, b[r] holds the answer to the query on [0,r].

  • »
    »
    3 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    the original requires update operation sadly, but thank u for spending precious time implement this!

»
3 months ago, # |
Rev. 7   Vote: I like it 0 Vote: I do not like it

To be able to get the hell out of this grey color, i'm learning new data structures

I wonder why no one pointed at this. To get out of grey color, you don't need to learn advanced data structures like Fenwick tree. Start with problems of rating 800 (if you are a newbie), solve 50-100 problems of 800 rating, then move to problems of rating 900,1000,1100....in a similar manner. Make sure you have sorted the problems in decreasing order of number of people who have solved it.

I am currently solving 1300 rating problems and haven't used anything fancy data structures/algorithms till now (like DFS,BFS,Dijkstra,DP etc). Forget about using Fenwick trees.

Also, focus on Div3 rated contests at this stage. It will help you increase your ratings. All the best !

  • »
    »
    3 months ago, # ^ |
    Rev. 3   Vote: I like it 0 Vote: I do not like it

    I'm currently self leaning maths from scratch (Pre algebra) and I'm currently in some basic geometry in algebra 1. I've almost solved every 800 rated problem tagged (geometry). What do you think of this approach to learning CP? :)

    • »
      »
      »
      3 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Yeah, its good. You need to practice problems related to topics you have learnt. Solving 100 problems related to every topic is an overkill imo. There are so many topics out there. It will be very time consuming.

      Also, if you want to increase your ratings faster, you should do what I wrote above.

»
3 months ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

really learning fenwick tree to get out of grey the tree is not needed until you want to reach exepert or even more sometimes dude go focus on solving B's,btw i still don't understand how you got to specialist unless your level magically got down