• [树状数组]求逆序对


    树状数组基本讲解:

    树状数组的用途就是求前缀和,他的本质跟线段树相似,就是一个空间换时间。

    主要采用lowbit,通过二进制从而划分区间。

    增加的时候,从下往上依次加lowbit

    查询的时候,从上往下减去lowbit。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <queue>
     8 #include <string>
     9 #include <vector>
    10 #define For(a,b) for(int a=0;a<b;a++)
    11 #define mem(a,b) memset(a,b,sizeof(a))
    12 #define _mem(a,b) memset(a,0,(b+1)<<2)
    13 #define lowbit(a) ((a)&-(a))
    14 using namespace std;
    15 typedef long long ll;
    16 const int maxn =  5*1e4+5;
    17 const int INF = 0x3f3f3f3f;
    18 int c[maxn];
    19 void update(int x,int y,int n){
    20     for(int i=x;i<=n;i+=lowbit(i))
    21         c[i] += y;
    22 }
    23 int getsum(int x){
    24     int ans = 0;
    25     for(int i=x;i;i-=lowbit(i))
    26         ans += c[i];
    27     return ans;
    28 }
    29 int main()
    30 {
    31     int t;
    32     int n;
    33     int x,y,z;
    34     string s;
    35     cin >> t ;
    36     for(int j=1;j<=t;j++){
    37         scanf("%d",&n);
    38         _mem(c,n);      //初始化数组中前n+1个数为0
    39         for(int i=1;i<=n;i++){
    40             scanf("%d",&z);
    41             update(i,z,n);
    42         }
    43         cout <<"Case "<<j<<":"<<endl;
    44         while(1){
    45             cin >> s;
    46             if(s[0] == 'E')
    47                 break;
    48             scanf("%d%d",&x,&y);
    49             if(s[0] == 'Q')
    50                 cout << getsum(y)-getsum(x-1)<<endl;
    51             else if(s[0] == 'A')
    52                 update(x,y,n);
    53             else
    54                 update(x,-y,n);
    55         }
    56     }
    57     return 0;
    58 }
    View Code

    求逆序对!

    ci 的意思是在前lowbit 中元素的个数。

    然后往前i个中的sum就是小于等于这个i的个数

    这个数的位置-小于等于这个i的个数 就是前面大于这个数的个数

    小于等于这个数的个数肯定比 这个数的位置要小。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<string>
     5 #include<cstring>
     6 #include<queue>
     7 #include<map>
     8 #include<set>
     9 #include<algorithm>
    10 using namespace std;
    11 typedef long long ll;
    12 const int N=1000+10;
    13 int c[N],n,aa;
    14 int lowbit(int x)
    15 {
    16     return x&-x;
    17 }
    18 void insert(int i,int x)
    19 {
    20     while(i<=n)
    21     {
    22         c[i]+=x;
    23         i+=lowbit(i);
    24     }
    25 }
    26 int getsum(int i)
    27 {
    28     int sum=0;
    29     while(i>0)
    30     {
    31         sum+=c[i];
    32         i-=lowbit(i);
    33     }
    34     return sum;
    35 }
    36 int main()
    37 {
    38     while(scanf("%d",&n)!=EOF)
    39     {
    40     int ans=0;
    41     memset(c,0,sizeof(c));
    42     for(int i=1;i<=n;i++)
    43     {
    44         scanf("%d",&aa);
    45         insert(aa,1);
    46         ans+=i-getsum(aa);
    47     }
    48     printf("%d
    ",ans);
    49     }
    50     return 0;
    51 }
    View Code

    挖个坑下回把归并和快排的求逆序对放下来。

     

    F - Cube

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <set>
     7 #include <map>
     8 #include <vector>
     9 #include <cctype>
    10 #include <sstream>
    11 using namespace std;
    12 typedef long long ll;
    13 const int inf=0x7fffffff;
    14 const int N=110;
    15 const int M=500000+10;
    16 int a[N][N][N],c[N][N][N];
    17 int n,m;
    18 int lowbit(int x)
    19 {
    20     return x&-x;
    21 }
    22 void insert(int x,int y,int z,int iii)
    23 {
    24     for(int i=x;i<=n;i+=lowbit(i))
    25         for(int j=y;j<=n;j+=lowbit(j))
    26             for(int k=z;k<=n;k+=lowbit(k))
    27                 c[i][j][k]+=iii;
    28 }
    29 int getsum(int x,int y,int z)
    30 {
    31     int sum=0;
    32     for(int i=x;i>0;i-=lowbit(i))
    33         for(int j=y;j>0;j-=lowbit(j))
    34             for(int k=z;k>0;k-=lowbit(k))
    35                 sum+=c[i][j][k];
    36     return sum;
    37 }
    38 int main()
    39 {
    40     while(scanf("%d %d",&n,&m)!=EOF)
    41     {
    42         memset(c,0,sizeof(c));
    43     int ss,xx,yy,zz;
    44     while(m--)
    45     {
    46         scanf("%d %d %d %d",&ss,&xx,&yy,&zz);
    47         if(ss==1)
    48         {
    49             int xxx,yyy,zzz;
    50             scanf("%d %d %d",&xxx,&yyy,&zzz);
    51             xxx++;  yyy++;  zzz++;
    52             insert(xx,yy,zz,1);
    53             insert(xx,yy,zzz,1);
    54             insert(xx,yyy,zz,1);
    55             insert(xx,yyy,zzz,1);
    56             insert(xxx,yy,zz,1);
    57             insert(xxx,yy,zzz,1);
    58             insert(xxx,yyy,zz,1);
    59             insert(xxx,yyy,zzz,1);
    60         }
    61         else
    62         {
    63             printf("%d
    ",getsum(xx,yy,zz)&1);
    64         }
    65     }
    66     }
    67 
    68     return 0;
    69 }
    View Code

     

    No matter how you feel, get up , dress up , show up ,and never give up.
  • 相关阅读:
    Asp.net MVC 3实例学习之ExtShop(三)——完成首页
    Asp.net MVC 3实例学习之ExtShop(一)————创建应用并设置开发环境
    JDK里的设计模式
    Linux系统下ssh的相关配置
    简单介绍asp模式与saas模式
    Linux系统中xorg.conf文件简介
    [C++] MurmurHash2的性能
    [C++] 在程序里调用DOS命令
    Android SDK 1.5中文版 (Application基础—1)
    linux系统单网卡绑定双IP的方法
  • 原文地址:https://www.cnblogs.com/Kaike/p/10318724.html
Copyright © 2020-2023  润新知