优化标准迭代算法

时间:2013-12-21 07:32:51

标签: c++ algorithm encryption optimization c-preprocessor

参考此处的问题挑战: Link

#include <iostream>

using namespace std;


int main() {
    int T,*x,i,j,k,a,res,pres;
    long Q,N,p,q;
    cin>>T;
    for(k=0;k<T;k++)
    {
        cin>>N>>Q;
        x=new int[N];
        for(i=0;i<N;i++)
        {
            cin>>x[i];
        }
        for(i=0;i<Q;i++)
        {
            pres=-999;
            cin>>a>>p>>q;
            for(j=p-1;j<q;j++)
            {
                res=a xor x[j];
                if(pres<res)
                {
                    pres=res;
                }
            }
            cout<<pres<<endl;

        }
        delete [] x;
    }
    return 0;
}

我在更大的问题(N = 100000)(N,Q,T最大值)上超出时间限制(暗示问题可以优化)。我想我需要使用某种预处理来优化算法。对于整个问题,我的解决方案是O(NQT)。该问题需要针对查询中给定限制的所有可能XOR进行评估。所以,问题需要(q-p)[可以在最大N]次查询。我无法想办法避免这种情况。一个命中或方向将非常感激。我正在考虑以某种方式实现堆,以便它从堆中减去查询a并且使最大堆看到最大差异和密度。但这也需要O(NQT)

3 个答案:

答案 0 :(得分:1)

我不认为摆弄你写的东西会让你受到很多速度的影响。你想要一个时间复杂度更高的东西。

从这个问题来看,我假设他们想要每个查询的O(log N)。我最初的想法是segment tree,但我找不到使用它们来最大化a ^ x[i]的方法。

我相信你应该使用所有数字都小于2^15的事实。另外需要注意的是,您希望最大化xor操作。假设你有(二进制)

a = b_1 b_2 ... b_n

您要么所有x[j]p <= j <= q的最高有效位等于b_1,要么有一些x[j],其中最重要的位是b_1的补充。这是因为b xor ~b = 1 b in {0,1}。您只选择MSB为j补码的b_1,然后继续下一位(对应b_2)。

问题在于,这种情况的蛮力实施比您已经在做的更糟糕,但它可能会帮助您更快地实施。

答案 1 :(得分:0)

一些提示:

  • cin的所有调用都无法衡量此代码的性能。你应该提前从文件中读取所有数据。
  • 不要为每个外观分配x,使用malloc分配一次,并在需要时调用realloc以使缓冲区更长。内存分配可能会减慢速度。

内部循环非常简单,因此编译器可以对其进行矢量化。通过查看反汇编确保实际发生这种情况。如果没有,请使用SSE内在函数一次处理4个或8个8个元素。

答案 2 :(得分:0)

以下是修改后的代码以及我在评论中提出的建议。

在性能敏感的代码中避免使用C ++ iostream。 (FWIW,一般避免iostreams) 尽可能避免分配/解除分配。在下面的代码中,vector::resize会 注意向量始终至少具有所需的空间。 不是性能,而是可读性:使用空间aronud运算符。声明变量关闭 到他们使用的地方。

#include <cstdio>
#include <vector>
#include <algorithm>

int main() {
    int T;
    std::vector<int> x;

    std::scanf ("%d", &T);
    for (int k = 0; k < T ; ++k) {

        int N, Q;
        std::scanf ("%d%d", &N, &Q);
        x.resize (N);

        for (int i = 0; i < N; ++i)
            std::scanf ("%d", &x[i]);

        for (int i = 0; i < Q; ++i) {
            int a, p, q;
            std::scanf ("%d%d%d", &a, &p, &q);

            int pres = -999;
            for(int j = p - 1; j < q; ++j)
                pres = std::max (pres, a ^ x[j]);

            std::printf ("%d\n", pres);
        }
    }
    return 0;
}