BIT树状数组

来源:互联网 发布:浪漫的c语言小程序 编辑:程序博客网 时间:2024/06/06 12:56
/*Binary indexed Tree    给定初始值全为0的数列 A1,A2,A3……An    1:给定i 求A1+A2+……+Ai    2:给定i和  X求Ai+=  X;*/# include<stdio.h># define N 101int SUM(int BIT[],int i){    int sum=0;    if(i>BIT[0]) i=BIT[0];    while(i>0){        sum+=BIT[i];        i&=i-1;      }      return sum;}void ADD(int BIT[],int i,int x){    while(i<=BIT[0]){        BIT[i]+=x;        i+=i&-i;    }}int main(){    int A[N]={0},i,t,j;    freopen("haha.txt","r",stdin);    scanf("%d ",&A[0]);    for(i=1;i<=A[0];i++)    {        scanf("%d",&t);        ADD(A,i,t);        for(j=1;j<=A[0];j++)        printf("%4d ",A[j]);        printf("\n");    }    for(i=1;i<=15;i++)        printf("%d\n",SUM(A,i));    return 0;}/*Binary indexed Tree    给定初始值全为0的数列 A1,A2,A3……An    1:给定i 求A1+A2+……+Ai    2:给定i和  X求Ai+=  X;    给定N个元素的{Ai}数组,求对这N个元素进行冒泡排序的所需的交换次数 N∈[1,100000]    冒泡排序是 一种 每次找到满足的Ai>Ai+1的i,并交换Ai和Ai+1 知道最后不存在这样的i的算法    EG:输入N=4  A={3,1,4,2};    输出 :3    解:    冒泡排序的复杂度为0(N^2) 显然不行 BIT 树状数组    逆序数:    i<j but AI>Aj的数对的个数    对于每一个j 如果能快速求出满足次条件的逆序数的i的个数,那么问题就迎刃而解    我们做如下操作:把j-(BIT[]查询所得到的前Aj的和加到答案中)    把BIT的A[j]++    对于每一个j,BIT[]查询所得到的Aj的前Aj项的和就是满足i<j ai<=aj的个数    j再减去这个数 就是逆序数的个数     对每一个J的操作都是0(logN)所以整个算法的复杂度0(NlogN);*/# include<stdio.h># define N 101int A[N];int SUM(int BIT[],int i)  //求前i项和{    int sum=0;    if(i>BIT[0]) i=BIT[0];  //为了防止形参错误导致数组越界    while(i>0){        sum+=BIT[i];  //求SUM        i&=i-1;  //移动i      }      return sum;}void ADD(int BIT[],int i,int x)  //把第i项改为BIT[i]+=x{    while(i&&i<=BIT[0]){        BIT[i]+=x;        i+=i&-i;    }}int main(){    long long sum=0;    int i,t;    //freopen("SSS.txt","r",stdin);    scanf("%d ",&A[0]);    for(i=1;i<=A[0];i++)        scanf("%d",&A[i]);    for(i=1;i<=A[0];i++)    {        sum+=i+1-SUM(A,A[i]+1);        ADD(A,A[i]+1,1);    }    printf("%lld\n",sum);    return 0;}


原创粉丝点击