GOODPROB from codechef, what's the algo?

时间:2016-08-31 12:10:49

标签: c++ math logic

I was just solving problems and came upon this one

Given an array A consisting of N integers - A1, A2....AN. You have to find the value of Σ MAX(i,j) * F(i,j) where 1 ≤ i < j ≤ N.

MAX(i,j) is defined as max(Ai,Ai+1...Aj).

F(i,j) is defined as:

F(i,j) will be 1 if (Ai&Aj) = Aj or (Ai&Aj) = Ai F(i,j) will be 0, otherwise. Here & denotes the bitwise AND operator.

reference: GOODPROB

I wrote a fairly simple solution and got 40 points, i.e. it could not handle large inputs in the required 2 seconds time.

This was my code

#include <iostream>
using namespace std;

int max(int *A, int x,int y){
    int m=A[x];
    while(x<=y){
        if(A[x]>m)
            m=A[x];
        x++;
    }
    return m;
}

int F(int *A,int i,int j){
    return ((A[i]&A[j]) == A[j] or (A[i]&A[j]) == A[i])?1:0;
    }
int main() {
    long N;
    cin>>N;
    int *A = new int[N];
    for(int i=0;i<N; i++)
        cin>>A[i];
    long m=0;
    for(int j=0;j<N;j++)
        for(int i=0;i<j; i++)
            m+= F(A,i,j)?max(A,i,j)*F(A,i,j):0;
    cout<<m<<endl;
    return 0;
} 

I checked the successful submitions there but those made me go panic. I couldn't even imagine such large solution for this fairly simple looking problem. Can anyone come up with a solution simple enough to understand.

2 个答案:

答案 0 :(得分:0)

OK this does not really give you an effective algorithm but the comment section does not give the best formatting options.

I have found some small optimization possibilities. You repeat statements sometimes when not needed.

m+= F(A,i,j)?max(A,i,j)*F(A,i,j):0;

Here you can store the result of F(A,i,j) and only call this function twice (function calls can be expensive).

return ((A[i]&A[j]) == A[j] or (A[i]&A[j]) == A[i])?1:0;

Same here with A[i]&A[j]. You could store the result beforehand.

So just some small things in your current algorithm. How much they will help / improve you have to measure yourself.

答案 1 :(得分:0)

您正在线性地找到数组范围内的最大值。 这样做会在总体复杂性中增加 O(n)因子。由于您使用嵌套循环并从内部调用max,因此您的整体时间复杂度将为 O(n ^ 3)

您可以使用细分树数据结构显着降低此因素。 使用分段树,您可以在 O(log(n))时间范围内找到最大值。 将总体复杂性降低到 O(n ^ 2 * log(n)) 有关范围最大/最小查询的教程

Range Minimum Query using Segment Tree