When submitting a solution in C++, please select either C++14 (GCC 6-32) or C++17 (GCC 7-32) as your compiler. ×

watchdogs132's blog

By watchdogs132, history, 4 years ago, In English

Link to problem: https://www.spoj.com/problems/FREQUENT/

I know this is quite a famous problem and I have searched extensively about it , but my attempts at debugging my code have failed.

I use the approach of Segment Trees to solve this problem after having built a frequency array. Run time : $$$O(n)$$$ pre-processing per test case and $$$O(log (n))$$$ to answer each query.

#include<iostream>
#include<algorithm>
#include<unordered_map>
 
using namespace std;
 
const int N=200000;
 
int a[N],t[4*N],b[N]; //b is the frequency array
 
void build(int v,int tl,int tr){
    if(tl==tr){
        t[v]=b[tl];
    }
    else{
    int tm=(tl+tr)/2;
    build(2*v,tl,tm);
    build(2*v+1,tm+1,tr);
    t[v]=max(t[2*v],t[2*v+1]);
    }
}
 
int query(int v,int tl,int tr,int l,int r){
    if(l>r)
        return -1e9;
    if(l<=tl&&tr<=r)
        return t[v];
    int tm=(tl+tr)/2;
    return max(query(v*2, tl, tm, l, min(r, tm)),
               query(v*2+1, tm+1, tr, max(l, tm+1), r));
}
int main()
{
      int n,q; 
      while(true){
        scanf("%d", &n);
        if(!n)break;
        scanf("%d", &q);
        unordered_map<int,int>cnt;
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            ++cnt[a[i]];
        }
        for(int i=0;i<n;i++){
            b[i]=cnt[a[i]];
        }
        build(1,0,n-1);
         while(q--){
            int l,r;
            scanf("%d %d",&l,&r);
            --l,--r;
            if(a[r]==a[l]){  //This is when all numbers in the range are the same.
                printf("%d\n",r-l+1);
            }
            else{
                /*This is to handle the case as follows :111 22233 4444
                  idx1 and idx2-1 will cover the range 22233 and
                  then we do the max of all three blocks [111] [22233] [4444] which
                  in this case is basically max(3,3,4)=4 */
                int idx1=upper_bound(a+l,a+l+r,a[l])-a;
                int idx2=lower_bound(a+l,a+l+r,a[r])-a;
                int ans=max(max(idx1-l,r+1-idx2),query(1,0,n-1,idx1,idx2-1));
                printf("%d\n",ans);
            }
         }
    }
 return 0;
} 
  • Vote: I like it
  • -2
  • Vote: I do not like it

| Write comment?
»
4 years ago, # |
  Vote: I like it +7 Vote: I do not like it

It is not too hard to write a brute force algorithm and a random test case generator for this problem. Once you have done this, I think that it wouldn't be too difficult to find a small counterexample to your solution which you can use for debugging.