树状数组

一.单点修改,区间查询

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll N=5*1e5+2;
 5 inline int read()
 6 {
 7     ll sm=0,flag=1;
 8     char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')flag=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9'){sm=sm*10+ch-'0';ch=getchar();}
11     return sm*flag;
12 }
13 ll n,m;
14 ll c[N];
15 ll lowbit(ll x)
16 {
17     return x&(-x);
18 }
19 void uphold(ll x,ll num)
20 {
21     while(x<=n)
22     {
23         c[x]+=num;
24         x+=lowbit(x);
25     }
26 }
27 ll ask(ll x)
28 {
29     ll ans=0;
30     while(x>=1)
31     {
32         ans+=c[x];
33         x-=lowbit(x);
34     }
35     return ans;
36 }
37 int main()
38 {
39     n=read();m=read();
40     for(ll i=1;i<=n;++i)
41     {
42         ll a=read();
43         uphold(i,a);
44     }
45     for(ll i=1;i<=m;++i)
46     {
47         ll type=read();
48         if(type==1)
49         {
50             ll x=read(),k=read();
51             uphold(x,k);
52         }
53         else if(type==2)
54         {
55             ll x=read(),y=read();
56             cout<<ask(y)-ask(x-1)<<endl;
57         }
58     }
59     return 0;
60 }
View Code

二.区间修改,单点查询

运用了前缀和的思想

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll N=5*1e5+2;
 5 inline int read()
 6 {
 7     ll sm=0,flag=1;
 8     char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')flag=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9'){sm=sm*10+ch-'0';ch=getchar();}
11     return sm*flag;
12 }
13 ll n,m;
14 ll c[N];
15 ll lowbit(ll x)
16 {
17     return x&(-x);
18 }
19 void uphold(ll x,ll num)
20 {
21     while(x<=n)
22     {
23         c[x]+=num;
24         x+=lowbit(x);
25     }
26 }
27 ll ask(ll x)
28 {
29     ll ans=0;
30     while(x>=1)
31     {
32         ans+=c[x];
33         x-=lowbit(x);
34     }
35     return ans;
36 }
37 int main()
38 {
39     n=read();m=read();
40     ll last=0;
41     for(ll i=1;i<=n;++i)
42     {
43         ll x=read();
44         uphold(i,x-last);
45         last=x;
46     }
47     for(ll i=1;i<=m;++i)
48     {
49         ll type=read();
50         if(type==1)
51         {
52             ll x=read(),y=read(),z=read();
53             uphold(x,z);uphold(y+1,-1*z);
54         }
55         else if(type==2)
56         {
57             ll x=read();
58             cout<<ask(x)<<endl;
59         }
60     }
61     return 0;
62 }
View Code

三.求逆序对

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn = 100010;
 5 const int maxm = 99999997;
 6 struct MyStruct
 7 {
 8     int data;
 9     int loc;
10 }a[maxn],b[maxn];
11 int e[maxn], n, c[maxn];
12 int inline readint()
13 {
14     int x = 0;
15     char c = getchar();
16     while (c<'0' || c>'9') c = getchar();
17     while (c >= '0'&&c <= '9')
18     {
19         x = x * 10 + c - '0';
20         c = getchar();
21     }
22     return x;
23 }
24 int lowbit(int x)
25 {
26     return x&-x;//树状数组实现 
27 }
28 void add(int x,int t)
29 {
30     while (x <= n)
31     {
32         e[x] += t;
33         e[x] %= maxm;
34         x += lowbit(x);//每次往后加,可以改变后面对应的和 
35     }
36 }
37 int sum(int x)
38 {
39     int s = 0;
40     while(x)
41     {
42         s += e[x];
43         s %= maxm;
44         x -= lowbit(x);//得到所求的和 
45     }
46     return s;
47 }
48 bool cmp(MyStruct x, MyStruct y)
49 {
50     return x.data < y.data;
51 }
52 int main()
53 {
54     n = readint();
55     for (int i = 1; i <= n; i++)
56     {
57         a[i].data = readint();
58         a[i].loc = i;//记录位置 
59     }
60     for (int i = 1; i <= n; i++)
61     {
62         b[i].data = readint();
63         b[i].loc = i;
64     }
65     sort(a + 1, a + n + 1, cmp);
66     sort(b + 1, b + n + 1, cmp);
67     for (int i = 1; i <= n; i++)
68     {
69         c[a[i].loc] = b[i].loc;//离散优化 
70     }
71     int ans = 0;
72     for (int i = 1; i <= n; i++)
73     {
74         add(c[i], 1);//离散优化后大小就是正确顺序的位置 
75         ans += i - sum(c[i]);//当前位置,减去之前比他大的数的个数  
76         ans %= maxm;
77     }
78     printf("%d", ans);
79     return 0;
80 }
View Code

 

posted @ 2021-11-19 20:40  yfmd  阅读(31)  评论(0编辑  收藏  举报