关于树状数组,我自己还不是特别熟练,只是做了两道题,感觉自己掌握的不好,他来总结一下,现在我只能说我理解了前两种的树状数组,最后还有一种该区间求区间的,我还没有看明白,有一道题目,链接(点击打开链接)这个题目要我想的话,我是怎么也想不出来要用树状数组做的,还是理解不深,还是太水,最近发现自己的代码能力又下降了一点,还是打代码打的少,有点生疏,其实这个代码的话我还是不是特别理解,现在复制一段代码上来,
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=32010;
int n,c[MAXN],cnt[MAXN];
inline int lowbit(int x)
{
return x&(-x);
}
void add(int i,int val)
{
while(i<MAXN)
{
c[i]+=val;
i+=lowbit(i);
}
}
int sum(int i)
{
int s=0;
while(i>0)
{
s+=c[i];
i-=lowbit(i);
}
return s;
}
int main() {
int x,y;
while(scanf("%d",&n)!=EOF)
{
memset(c,0,sizeof(c));
memset(cnt,0,sizeof(cnt));
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
cnt[sum(x+1)]++;
add(x+1,1);
}
for(int i=0;i<n;i++)
{
printf("%d\n",cnt[i]);
}
}
return 0;
}
这个代码就是用树状数组做的,但是我其实还不知道为啥,英语也是越来越差了,这类文章就是考察细节的嘛,但是我对于英语的理解能力也是浅尝辄止,还是太水啊,上一个星期做了kmp,似乎好像有点熟练,其实呢,我的理解还是特别的弱,几乎没有理解什么,还是要多做题目啊,我不想再颓废下去了,
下面粘上树状数组的前两种方法,
来表示我已经学习过了
算了,其实我看到一个博客挺好的,几乎可以囊括我的了(点击打开链接)
其实我本该自己总结下的,以后吧,,,,,,,
补充一点:改段求段的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 100005
#define ll __int64
ll b[N], c[N];
int n;
int lowbit(int x) {
return x & (-x);
}
void update_backwards(int index, ll val) {
for (int i = index; i <= n; i += lowbit(i))
b[i] += val;
}
void update_forward(int index, ll val) {
for (int i = index; i; i -= lowbit(i))
c[i] += val;
}
void update(int index, ll val) {
update_backwards(index, index * val);
update_forward(index - 1, val);
}
ll query_forward(int index) {
ll ans = 0;
for (int i = index; i; i -= lowbit(i))
ans += b[i];
return ans;
}
ll query_backwards(int index) {
ll ans = 0;
for (int i = index; i <= n; i += lowbit(i))
ans += c[i];
return ans;
}
ll query(int index) {
return query_forward(index) + query_backwards(index) * index;
}
//---------------- main -------------- //
int main() {
int t, x, y;
ll z;
char str[2];
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
scanf("%d%d", &n, &t);
n += 1;
for (int i = 1; i < n; i++) {
scanf("%I64d", &z);
x = i + 1, y = i + 1;
update(y, z);
update(x - 1, -z);
}
while (t--) {
scanf("%s", str);
if (str[0] == 'C') {
scanf("%d%d%I64d", &x, &y, &z);
x += 1, y += 1;
update(y, z);
update(x - 1, -z);
} else {
scanf("%d%d", &x, &y);
x += 1, y += 1;
printf("%I64d\n", query(y) - query(x - 1));
}
}
return 0;
}
题目链接: 点击打开链接
该题是改段求段的模板题,还是感觉难以理解,晚上在记忆一遍,,,,,