diff --git a/c++/Bit_Manipulation/Fenwick_Tree.cpp b/c++/Bit_Manipulation/Fenwick_Tree.cpp new file mode 100644 index 0000000..be38c43 --- /dev/null +++ b/c++/Bit_Manipulation/Fenwick_Tree.cpp @@ -0,0 +1,128 @@ +//Fenwick Tree(Binary Indexed Tree) +//Make a structure to handle Dynamic Range queries +/* +LSB-Least Significant Bit +it is the rightmost set Bit in the Binary representation of a number. + +One's complement: + it is the value obtained by inverting all the zeros of binary representation of the number + +Two's complement: + =One's complement + 1 + +How LSB can be found? + LSB is the common set bit among the number and it's Two's complement. + +How to find Two's complement? + Negative of a number is stored as Two's complement the number in computers. + +Hence LSB= num & (-num) +*/ + +#include +#define ll long long int +using namespace std; + +class Fenwick +{ + //ith element of the tree stores the sum of last LSB(i) indexes(including ith index) + //where LSB(k) represents the Decimal equivalent of k + vector tree; + public: + int n; + vector arr; + //constructor to recieve size of tree and the vector + Fenwick(vector &tarr) + { + n=tarr.size(); + arr.clear(); + + arr.push_back(0); //Push zero to front of array to make it one based + for(auto &i:tarr) + { + arr.push_back(i); + } + + //using one based indexing for tree + tree.resize(n+1); + build(); + } + + //Build function to add the array values to the tree + //Adding elements using update query for each index + void build() + { + tree[0]=0; + for(int i=1;i<=n;i++) + { + treeupdate_add(i,arr[i]); + } + } + + //Function to add val to xth index of arr + //Pass the index and the value to be added + //Time-complexity => O(log(n)) + void treeupdate_add(int x,ll val) + { + while(x<=n) + { + tree[x]+=val; + x+=(x&(-x)); //Next update occurs after LSB(x) indexes + } + } + + //sum_qurey gives the sum of first x indexes + //Time-Complexity => O(log(n)) + ll sum_query(int x) + { + if(x==0) + return 0; + //Since tree[x] stores the sum of last LSB indexes + //we make a recursive call of sum query of first x-LSB(x) indexes. + return tree[x]+sum_query(x -(x&(-x))); + } + + //Sum of range [l,r] can be calculated using sum_query(r)-sum_query(l-1) + ll range_sum(int l,int r) + { + return sum_query(r)-sum_query(l-1); + } +}; + +//Driver code +int main() +{ + + vector arr={4,3,2,5,1,6,7,8}; + Fenwick f(arr); //passing the array in constructor + //sum of range [3,6] + cout<>n>>q; + // vector arr(n); + // for(auto &i:arr) cin>>i; + // Fenwick f(arr); + // for(int i=0;i>w; + // if(w==1) + // { + // int k,u; + // cin>>k>>u; + // f.treeupdate_add(k,u-arr[k-1]); + // arr[k-1]=u; + // } + // else + // { + // int l,r; + // cin>>l>>r; + // cout< +using namespace std; +#define MOD 1000000007 + +//Modular Exponentiation function such that 0<=a,b,M<=10^9 +//Time-Complexity => O(log(b)) +int ModularExp(int a,int b,int M) +{ + // base a + //power b + //modular M + //(a^b)%M + + int ans=1; + while(b>0) + { + //Each time we check the rightmost bit of b and then we right-shift it. + if(b&1) + { + ans=(ans*1ll*a)%M; + } + //In the exxpression it can be seen that value of a gets squared in each step. + a=(a*1ll*a)%M; + b>>=1; + } + return ans; +} + +//Modular Multiplication such that 0<=a,b,M<=10^18 +//Time-Complexity O(log(b)) +long long ModularMultiply_Big(long long a,long long b,long long M) +{ + // (a*b) mod M + long long ans=0; + while(b>0) + { + if(b&1) + { + ans=(ans + a)%M; + } + a=(a + a)%M; + b>>=1; + } + return ans; +} + +//Modular Exponentiation such that 0<=a,b,M<=10^18 +//Time-Complexity => O(log(b)*log(M)) +long long ModularExp_Big(long long a,long long b,long long M) +{ + long long ans=1; + while(b>0) + { + if(b&1) + { + //Direct multiplication cannot be used as (ans*a) can exceed LONG_LONG_MAX + ans=ModularMultiply_Big(ans,a,M); + } + //Direct multiplication cannot be used as (a*a) can exceed LONG_LONG_MAX + a=ModularMultiply_Big(a,a,M); + b>>=1; + } + return ans; +} + +//Driver Code +int main() +{ + cout< +using namespace std; +#define ll long long int + +//Time-Compleity => O(n*(2^n)) //n is the size of original set +vector> subsets_generate(vector& arr) +{ + //here n is arr.size() + long long sz=1<> subsets(sz); + for(long long i=0;i arr={3,4,7}; //Sample input array + vector> subsets=subsets_generate(arr); + //Printing each subset in each line + for(auto &i:subsets) + { + cout<<"{"; + for(auto &j:i) + { + cout<