我有一个 Fenwick 树的以下实现来解决 HackeEarth 上的以下问题。
#include <iostream>
#define MAX 1000000007
using namespace std;
long long int dp[500006];
long long int GCD[500006];
// Function to Calculate GCD
int gcd(int u, int v){
int shl = 0;
while ( u && v && u!=v ) {
bool eu = !(u & 1);
bool ev = !(v & 1);
if ( eu && ev ) {
++shl;
u >>= 1;
v >>= 1;
}
else if ( eu && !ev ) u >>= 1;
else if ( !eu && ev ) v >>= 1;
else if ( u>=v ) u = (u-v)>>1;
else {
int tmp = u;
u = (v-u)>>1;
v = tmp;
}
}
return !u? v<<shl : u<<shl;
}
//Function to calculate Cumulative GCD
long long int cumulativeGCD(int x){
long long int sum = 0;
if(!dp[x]){
for(int i=1;i<=x;i++){
sum += gcd(i,x);
}
dp[x] = sum;
return sum;
}
else return dp[x];
}
// Retrieve the SUM function
long long int getSum(long long int BITree[], int index)
{
long long int sum = 0; // Iniialize result
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse ancestors of BITree[index]
while (index>0)
{
// Add current element of BITree to sum
sum += BITree[index];
// Move index to parent node in getSum View
index -= index & (-index);
}
return sum;
}
// Update BIT function
void updateBIT(long long int BITree[], int n, int index, long long int val)
{
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse all ancestors and add 'val'
while (index <= n)
{
// Add 'val' to current node of BI Tree
if(BITree[index]>MAX)
BITree[index] = (BITree[index] + val)%MAX;
else BITree[index] += val;
// Update index to that of parent in update View
index += index & (-index);
}
}
// Construct BIT function
long long int *constructBIT(int arr[], int size){
long long int *BITree = new long long int[size+1]();
for (int i=0; i<size; i++)
updateBIT(BITree, size, i, GCD[i]);
return BITree;
}
int main()
{
int size,queries,index,value,start,end;
char type;
scanf("%d",&size);
int *arr= new int[size];
for(int i=0;i<size;i++){
scanf("%d",&arr[i]);
GCD[i] = cumulativeGCD(arr[i]);
}
long long int *BIT = constructBIT(arr,size);
scanf("%d",&queries);
while(queries--){
cin>>type;
if(type=='C'){
scanf("%d %d",&start,&end);
printf("%lld\n",getSum(BIT,end-1) - getSum(BIT,start-2));
}
if(type=='U'){
scanf("%d %d",&index,&value);
long long int diff = cumulativeGCD(value)-cumulativeGCD(arr[index-1]);
updateBIT(BIT,size,index-1,diff);
}
}
return 0;
}
我的解决方案是超过 10 个测试用例中的 7 个的时间限制。我无法进一步优化此代码。我怎么可能优化它,以便它可以在每个测试用例的 1 秒内运行。非常感谢 !