树状数组笔记

代码越短,理解越难~ 

树状数组维护序列

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #define lowbit(a) (a&-a)
 7 using namespace std;
 8 int n,q,l,r,a[100001],tree[400001];
 9 char ord[5];
10 void add(int u,int val){
11     for(;u<=n;u+=lowbit(u)){
12         tree[u]+=val;
13     }
14 }
15 int query(int u){
16     int ans=0;
17     for(;u>0;u-=lowbit(u)){
18         ans+=tree[u];
19     }
20     return ans;
21 }
22 int main(){
23     memset(tree,0,sizeof(tree));
24     scanf("%d%d",&n,&q);
25     for(int i=1;i<=n;i++){
26         scanf("%d",&a[i]);
27         add(i,a[i]);
28     }
29     for(int i=1;i<=q;i++){
30         scanf("%s%d%d",ord,&l,&r);
31         if(ord[0]=='A'){
32             add(l,r);
33         }else if(ord[0]=='Q'){
34             printf("%d\n",query(r)-query(l-1));
35         }
36     }
37     return 0;
38 }

逆序数对

(为什么反而更短???)

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #define lowbit(n) (n&-n)
 7 typedef long long ll;
 8 using namespace std;
 9 int n,s,ans=0,tree[400001]; 
10 void add(int u,int val){
11     for(;u<=n;u+=lowbit(u)){
12         tree[u]+=val;
13     }
14 }
15 int query(int u){
16     int ans=0;
17     for(;u>0;u-=lowbit(u)){
18         ans+=tree[u];
19     }
20     return ans;
21 }
22 int main(){
23     scanf("%d",&n);
24     for(int i=1;i<=n;i++){
25         scanf("%d",&s);
26         ans+=(i-1-query(s-1));
27         add(s,1);
28     }
29     printf("%d",ans);
30     return 0;
31 }

 

posted @ 2018-07-09 15:35  DCDCBigBig  阅读(128)  评论(0编辑  收藏  举报