C++ 如何使用BIT解决此问题?

C++ 如何使用BIT解决此问题?,c++,algorithm,math,data-structures,discrete-mathematics,C++,Algorithm,Math,Data Structures,Discrete Mathematics,我发现了一个很好的数学问题,但我仍然不能解决它,我试图用谷歌找到一个解决方案,发现它可以用二叉索引树数据结构来解决,但解决方案我不清楚 这里的问题叫做寻找魔法三胞胎,可以在Uva在线评委中找到: (a+b^2)mod k=c^3 mod k,其中a是否决定使用位?我原以为普通数组就可以了。我首先创建三个大小为k的数组,其中arrayA[I]=范围内a的值的数量等于I mod k,arrayB[I]=范围内b的值的数量,其中b^2=I mod k,arrayC[I]=范围内c的值的数量,其中c^3

我发现了一个很好的数学问题,但我仍然不能解决它,我试图用谷歌找到一个解决方案,发现它可以用二叉索引树数据结构来解决,但解决方案我不清楚

这里的问题叫做寻找魔法三胞胎,可以在Uva在线评委中找到:


(a+b^2)mod k=c^3 mod k,其中a是否决定使用位?我原以为普通数组就可以了。我首先创建三个大小为k的数组,其中arrayA[I]=范围内a的值的数量等于I mod k,arrayB[I]=范围内b的值的数量,其中b^2=I mod k,arrayC[I]=范围内c的值的数量,其中c^3=I mod k。N和k都是。你能添加一些测试用例,以便验证任何解决方案吗?@MarkusJarderot[link]有问题的链接,例如N=10和k=7有27个不同的三元组。那么你是在试图理解这个解决方案,还是它不起作用?不太清楚你真正的问题是什么。是的,我试着去理解它,我明白了。只有一个答案帮助我解决了这个问题。@user2456277请接受下面的答案或写下你自己的答案,以便其他人可以从这个问题中学习。谢谢你的回答,但我不得不说你的解决方案根本不正确,首先,因为我想你没有考虑到以下事实:,位对于
sum
add
都具有
log(n)
复杂性,因此OP的解决方案是
O(n*log(K))
好的,思想类似于此,算法开始将b从n设置为1,因为c应该大于b,所以当b是n时,c的唯一可能值也是n,那么b是n-1,c可以是n-1或n,N已经在位中,因此设置c=N-1并将该值添加到位中就足够了,最后a的值的数量是len/K,整数除法提供了每个余数的数量。
#include <cstdio>
#include <cstring>
using namespace std;

typedef long long int64;

const int MAX_K = (int)(1e5);

int N, K;

struct BinaryIndexedTree{

    typedef int64 bit_t;

    static const int MAX_BIT = 3*MAX_K + 1;
    bit_t data[MAX_BIT+1];
    int SIZE;

    void init(int size){
        memset(data, 0, sizeof(data));
        SIZE = size;
    }

    bit_t sum(int n){
        bit_t ret = 0;
        for(;n;n-=n&-n){
            ret += data[n];
        }
        return ret;
    }

    bit_t sum(int from, int to){
        return sum(to)-sum(from);
    }

    void add(int n, bit_t x){
        for(n++;n<=SIZE;n+=n&-n){
            data[n]+=x;
        }
    }
};

BinaryIndexedTree bitree;


void init(){
    scanf("%d%d", &N, &K);
}

int64 solve(){
    bitree.init(2*K+1);

    int64 ans = 0;
    for(int64 i=N; i>=1; i--){
        int64 b = i * i % K, c = i * i * i % K;
        bitree.add(c, 1);
        bitree.add(c+K, 1);
        bitree.add(c+2*K, 1);
        int64 len = i;
        if(len >= K){
            ans += (len / K) * bitree.sum(K);
            len %= K;
        }
        if(len > 0){
            ans += bitree.sum(b + 1, b + len + 1);
        }
    }

    return ans;
}

int main(){
    int T;
    scanf("%d", &T);
    for(int i=0; i<T; i++){
        init();
        printf("Case %d: %lld\n", i+1, solve());
    }

    return 0;
}