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.
答案 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)) 有关范围最大/最小查询的教程