树状数组总结

关于树状数组,我自己还不是特别熟练,只是做了两道题,感觉自己掌握的不好,他来总结一下,现在我只能说我理解了前两种的树状数组,最后还有一种该区间求区间的,我还没有看明白,有一道题目,链接(点击打开链接)这个题目要我想的话,我是怎么也想不出来要用树状数组做的,还是理解不深,还是太水,最近发现自己的代码能力又下降了一点,还是打代码打的少,有点生疏,其实这个代码的话我还是不是特别理解,现在复制一段代码上来,

代码:

#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;
}

题目链接: 点击打开链接

该题是改段求段的模板题,还是感觉难以理解,晚上在记忆一遍,,,,,

微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值