暑假集训第八天

        在暑假集训这八天,让我对算法和数据结构,还有关于ACM比赛了解很多,知道了很多,能够在假期集训的人我认为都属于敢于面对自己,认识自己,能够迎难而上的人吧。

        从第一天开始每天都在学习新的知识,第一天学习背包(01背包,完全背包,多重背包),不算之前讲的二分、位运算和离散化什么的,应该是我第一次对算法这么深入的接触吧,第一天学习自我感觉状态不是很好,然后不知道如何去学习,接受起来比较困难吧,之后的每一天都在调整自己的状态,让自己能够更好的去接受新的知识。

        第二天学的动态规划(dp),动态规划,感觉就像数学推导公式一样,只要把状态转移方程推出来,然后代码细节方面注意一下就OK了(可是我好像推不出来)。

第三天学的栈、队列和搜索,栈和队列是一个新学的数据结构,搜索就是深搜和广搜,深搜就是递推,广搜就是从起始地点向外进行扩展,找到终点结束,在过程中要标记一下,不能走之前走过的路。

       第四天学的是并查集和堆,感觉并查集比堆好接受一点,堆就比较抽象,不太好理解,堆就是一个完全二叉树,左子树等于父节点的节点下标n*2,右子树等于父节点的节点下标n*2+1,然后就是堆要实现的功能,并查集就是有很多个集合要判断是不是同一个集合,或者将不同集合合并为一个集合,就是去找集合的根节点,然后进行判断,如果根节点相同则为同一个集合,如果不同,要将两个集合进行合并的话,就要让其中一个集合的根节点作为另一个集合的子节点。

       第五天学习图论、Dijkstra、Bellman–Ford和Ford。这天应该是我最近这几天最自闭的一天,刚接触图就不太理解,比之前学的堆还难理解,这个东西就是要多去看,多去学,不然怎么能会呢,后边三个算法是算最短路径的三个算法,第一个迪杰斯特拉算法是单源最短路径,它不能计算有负权的情况,第二个贝尔曼福德的算法就可以解决有负权的问题,但是要判断是否有负环,Ford算法是多源最短路,应该就是动态规划问题,要知道这三个算法的证明过程。

        第六天学习最小生成树和拓扑排序,推最小生成树有两种方法prim和kruskal,prim是以点来计算的,方法就是先以起点开始,将起点放入S集合内,然后找到未在集合S内距离S最近的点t,将t点放入集合S中,用t去更新指出的点距离S的值,这个算法可应用优先队列去优化,就是在寻找t的时候优化。kruskal算法是把所有边按照边权排序,然后访问所有边,判断是否在同一集合内,若不在就加入这条边。拓扑排序就是要找到入度为零的点,把从该指出的边删除,优化方式就是找入度为一的点。

          第七天学的是KMP和字符串哈希,KMP就是字符串进行匹配,最重要的是理解next数组是如何求得的,证明过程要详细了解,字符串哈希的话,就不太会应用,有一个假定条件,就是假定你的人品足够好,字符串哈希不会冲突。

          今天学的是树状数组和线段树,这两个东西要搞明白思路,要注意细节,一定要注意细节!!!我今天写代码,找BUG找了一下午,测试数据就是就能过,交上去就不对,原因就是少打了一个“=”号,判断里面的条件一定要仔细辨别。

在之后的假期集训时,要相信自己,勇于面对自己,一起加油吧。

这个是线段树或者树状数组的模板题的代码(这里只有线段树,树状数组的BUG找了快一天了还没找出来呢):

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 2e5 + 10;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
int tr[4 * N];
int f[N*4];
void pushUp(int rt) {
	tr[rt] = tr[rt<<1]+tr[rt<<1|1];
}
void build(int rt, int l, int r) {
	if (l == r) {
		tr[rt] = f[l];
		/*printf("%d ", tr[rt]);*/
		
		return;
	}
	int m = (l + r) >> 1;
	build(lson);
	build(rson);
	pushUp(rt);
}
void updata(int rt, int l, int r, int u, int num) {
	if (l == r) {
		tr[rt] += num;
		return;
	}
	int m = (l + r) >> 1;
	if (u <= m)updata(lson, u, num);
	else updata(rson, u, num);
	pushUp(rt);
}
int query(int rt, int l, int r, int L, int R) {
	if (L <= l && r <= R)
		return tr[rt];
	if()
	int m = (l + r) >> 1;
	int maxl = 0;
	if (L <= m) maxl += query(lson, L, R);
	if (R >= m + 1)maxl += query(rson, L, R);
	return maxl;
}
int main() {
	int n, m, t;
	scanf("%d", &t);
	for (int j = 1; j <= t; j++) {
		scanf("%d", &n);
		memset(f, 0, sizeof(f));
		for (int i = 1; i <= n; i++) {
			scanf("%d", &f[i]);
		}
		build(1, 1, n);
		char s[10];
		int x, y;
		printf("Case %d:\n", j);
		
		while (scanf("%s", s)&&s[0] != 'E') {
			scanf("%d %d", &x, &y);
			if (s[0] == 'Q') {
				printf("%d\n", query(1, 1, n, x, y));
			}
			else if (s[0] == 'A') {
				updata(1, 1, n, x, y);
				/*for (int i = 1; i <= 4*n; i++) {
					printf("%d\n", tr[i]);
				}	*/
			}
			else if (s[0] == 'S') {
				updata(1, 1, n, x, -1*y);
				/*for (int i = 1; i <= 4 * n; i++) {
					printf("%d\n", tr[i]);
				}*/
			}
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值